diff options
Diffstat (limited to 'indra')
395 files changed, 11169 insertions, 3150 deletions
diff --git a/indra/cmake/FMOD.cmake b/indra/cmake/FMOD.cmake index cb5124812d..cb5124812d 100755..100644 --- a/indra/cmake/FMOD.cmake +++ b/indra/cmake/FMOD.cmake diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index cfccd29def..4cbf7aa043 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -102,7 +102,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # To support a different SDK update these Xcode settings: set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5) set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk) - set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.2") + set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.0") set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym) # NOTE: To attempt an i386/PPC Universal build, add this on the configure line: diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index ce2d1e0386..ce2d1e0386 100755..100644 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 80df91a5c1..9910281b64 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -115,6 +115,7 @@ set(llcommon_HEADER_FILES indra_constants.h linden_common.h linked_lists.h + llaccountingquota.h llallocator.h llallocator_heap_profile.h llagentconstants.h diff --git a/indra/llcommon/llaccountingquota.h b/indra/llcommon/llaccountingquota.h new file mode 100644 index 0000000000..140333de07 --- /dev/null +++ b/indra/llcommon/llaccountingquota.h @@ -0,0 +1,80 @@ +/** + * @file llaccountingquota.h + * @ + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_ACCOUNTINGQUOTA_H +#define LL_ACCOUNTINGQUOTA_H + +struct ParcelQuota +{ + ParcelQuota( F32 ownerRenderCost, F32 ownerPhysicsCost, F32 ownerNetworkCost, F32 ownerSimulationCost, + F32 groupRenderCost, F32 groupPhysicsCost, F32 groupNetworkCost, F32 groupSimulationCost, + F32 otherRenderCost, F32 otherPhysicsCost, F32 otherNetworkCost, F32 otherSimulationCost, + F32 tempRenderCost, F32 tempPhysicsCost, F32 tempNetworkCost, F32 tempSimulationCost, + F32 selectedRenderCost, F32 selectedPhysicsCost, F32 selectedNetworkCost, F32 selectedSimulationCost, + F32 parcelCapacity ) + : mOwnerRenderCost( ownerRenderCost ), mOwnerPhysicsCost( ownerPhysicsCost ) + , mOwnerNetworkCost( ownerNetworkCost ), mOwnerSimulationCost( ownerSimulationCost ) + , mGroupRenderCost( groupRenderCost ), mGroupPhysicsCost( groupPhysicsCost ) + , mGroupNetworkCost( groupNetworkCost ), mGroupSimulationCost( groupSimulationCost ) + , mOtherRenderCost( otherRenderCost ), mOtherPhysicsCost( otherPhysicsCost ) + , mOtherNetworkCost( otherNetworkCost ), mOtherSimulationCost( otherSimulationCost ) + , mTempRenderCost( tempRenderCost ), mTempPhysicsCost( tempPhysicsCost ) + , mTempNetworkCost( tempNetworkCost ), mTempSimulationCost( tempSimulationCost ) + , mSelectedRenderCost( tempRenderCost ), mSelectedPhysicsCost( tempPhysicsCost ) + , mSelectedNetworkCost( tempNetworkCost ), mSelectedSimulationCost( selectedSimulationCost ) + , mParcelCapacity( parcelCapacity ) + { + } + + ParcelQuota(){} + F32 mOwnerRenderCost, mOwnerPhysicsCost, mOwnerNetworkCost, mOwnerSimulationCost; + F32 mGroupRenderCost, mGroupPhysicsCost, mGroupNetworkCost, mGroupSimulationCost; + F32 mOtherRenderCost, mOtherPhysicsCost, mOtherNetworkCost, mOtherSimulationCost; + F32 mTempRenderCost, mTempPhysicsCost, mTempNetworkCost, mTempSimulationCost; + F32 mSelectedRenderCost, mSelectedPhysicsCost, mSelectedNetworkCost, mSelectedSimulationCost; + F32 mParcelCapacity; +}; + +struct SelectionQuota +{ + SelectionQuota( LLUUID localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost ) + : mLocalId( localId) + , mRenderCost( renderCost ) + , mPhysicsCost( physicsCost ) + , mNetworkCost( networkCost ) + , mSimulationCost( simulationCost ) + { + } + SelectionQuota() {} + + F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost; + LLUUID mLocalId; +}; + +#endif + + + diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index 87c2d6775b..f5b242fdfc 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -49,7 +49,8 @@ typedef enum e_chat_type CHAT_TYPE_STOP = 5, CHAT_TYPE_DEBUG_MSG = 6, CHAT_TYPE_REGION = 7, - CHAT_TYPE_OWNER = 8 + CHAT_TYPE_OWNER = 8, + CHAT_TYPE_DIRECT = 9 // From llRegionSayTo() } EChatType; typedef enum e_chat_audible_level diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 5be5ecc492..bf62600514 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -2036,7 +2036,9 @@ std::string zip_llsd(LLSD& data) { //copy result into output if (strm.avail_out >= CHUNK) { - llerrs << "WTF?" << llendl; + free(output); + llwarns << "Failed to compress LLSD block." << llendl; + return std::string(); } have = CHUNK-strm.avail_out; diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index 8ba97d7730..b2c495d093 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -737,7 +737,7 @@ void LLPerfBlock::addStatsToLLSDandReset( LLSD & stats, } } else - { // WTF? Shouldn't have a NULL pointer in the map. + { // Shouldn't have a NULL pointer in the map. llwarns << "Unexpected NULL dynamic stat at '" << stats_full_path << "'" << llendl; } } diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index ca2d3f9181..e8616a9be6 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -188,22 +188,30 @@ LLOSInfo::LLOSInfo() : if(osvi.wProductType == VER_NT_WORKSTATION) mOSStringSimple = "Microsoft Windows XP x64 Edition "; else - mOSStringSimple = "Microsoft Windows Server 2003 "; + mOSStringSimple = "Microsoft Windows Server 2003 "; } - else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 1) + else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 2) { if(osvi.dwMinorVersion == 0) { - mOSStringSimple = "Microsoft Windows Vista "; + if(osvi.wProductType == VER_NT_WORKSTATION) + mOSStringSimple = "Microsoft Windows Vista "; + else + mOSStringSimple = "Windows Server 2008 "; } else if(osvi.dwMinorVersion == 1) { - mOSStringSimple = "Microsoft Windows 7 "; + if(osvi.wProductType == VER_NT_WORKSTATION) + mOSStringSimple = "Microsoft Windows 7 "; + else + mOSStringSimple = "Windows Server 2008 R2 "; } - - if(osvi.wProductType != VER_NT_WORKSTATION) + else if(osvi.dwMinorVersion == 2) { - mOSStringSimple += "Server "; + if(osvi.wProductType == VER_NT_WORKSTATION) + mOSStringSimple = "Microsoft Windows 8 "; + else + mOSStringSimple = "Windows Server 2012 "; } ///get native system info if available.. @@ -308,8 +316,7 @@ LLOSInfo::LLOSInfo() : std::string compatibility_mode; if(got_shell32_version) { - if(osvi.dwMajorVersion != shell32_major - || osvi.dwMinorVersion != shell32_minor) + if(osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) { compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)", shell32_major, diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 7703132d90..92cd9bd46a 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -29,7 +29,7 @@ const S32 LL_VERSION_MAJOR = 2; const S32 LL_VERSION_MINOR = 7; -const S32 LL_VERSION_PATCH = 0; +const S32 LL_VERSION_PATCH = 5; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 0a4cd51ea0..e8cd871157 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -1348,3 +1348,12 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s) // is a distinct option from "None" and "Other" return LLParcel::C_ANY; } + +void LLParcel::updateQuota( const LLUUID& objectId, const ParcelQuota& quota ) +{ + if ( mID == objectId ) + { + mQuota = quota; + } +} + diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 71b65d99ce..4893337967 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -34,7 +34,7 @@ #include "llpermissions.h" #include "lltimer.h" #include "v3math.h" - +#include "llaccountingquota.h" // Grid out of which parcels taken is stepped every 4 meters. const F32 PARCEL_GRID_STEP_METERS = 4.f; @@ -586,7 +586,11 @@ public: LLUUID getPreviousOwnerID() const { return mPreviousOwnerID; } BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; } BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; } - + + + void updateQuota( const LLUUID& objectId, const ParcelQuota& quota ); + const ParcelQuota& getQuota( void ) { return mQuota; } + protected: LLUUID mID; LLUUID mOwnerID; @@ -657,8 +661,9 @@ protected: BOOL mRegionPushOverride; BOOL mRegionDenyAnonymousOverride; BOOL mRegionDenyAgeUnverifiedOverride; - - + + ParcelQuota mQuota; + public: // HACK, make private S32 mLocalID; diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 39ae09650e..c156ed0cef 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -73,7 +73,7 @@ void set_default_colour_weights(kdu_params *siz); const char* engineInfoLLImageJ2CKDU() { - std::string version = llformat("KDU %s", KDU_CORE_VERSION); + static std::string version = llformat("KDU %s", KDU_CORE_VERSION); return version.c_str(); } diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index fdfc24f8b7..e5ca47da69 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -35,12 +35,14 @@ #define OCT_ERRS LL_WARNS("OctreeErrors") -#define LL_OCTREE_PARANOIA_CHECK 0 + +extern U32 gOctreeMaxCapacity; +/*#define LL_OCTREE_PARANOIA_CHECK 0 #if LL_DARWIN #define LL_OCTREE_MAX_CAPACITY 32 #else #define LL_OCTREE_MAX_CAPACITY 128 -#endif +#endif*/ template <class T> class LLOctreeNode; @@ -74,6 +76,7 @@ template <class T> class LLOctreeNode : public LLTreeNode<T> { public: + typedef LLOctreeTraveler<T> oct_traveler; typedef LLTreeTraveler<T> tree_traveler; typedef typename std::set<LLPointer<T> > element_list; @@ -294,8 +297,8 @@ public: //is it here? if (isInside(data->getPositionGroup())) { - if ((getElementCount() < LL_OCTREE_MAX_CAPACITY && contains(data->getBinRadius()) || - (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) + if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) || + (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here #if LL_OCTREE_PARANOIA_CHECK //if this is a redundant insertion, error out (should never happen) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c504215ee5..8c81f27784 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -100,7 +100,7 @@ void assert_aligned(void* ptr, uintptr_t alignment) uintptr_t t = (uintptr_t) ptr; if (t%alignment != 0) { - llerrs << "WTF?" << llendl; + llerrs << "Alignment check failed." << llendl; } #endif } @@ -361,7 +361,7 @@ public: } else { - llerrs << "WTF? Empty leaf" << llendl; + llerrs << "Empty leaf" << llendl; } for (S32 i = 0; i < branch->getChildCount(); ++i) @@ -416,6 +416,70 @@ LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BO return face; } +//static +S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split) +{ // this is basically LLProfile::genNGon stripped down to only the operations that influence the number of points + LLMemType m1(LLMemType::MTYPE_VOLUME); + S32 np = 0; + + // Generate an n-sided "circular" path. + // 0 is (1,0), and we go counter-clockwise along a circular path from there. + F32 t, t_step, t_first, t_fraction; + + F32 begin = params.getBegin(); + F32 end = params.getEnd(); + + t_step = 1.0f / sides; + + t_first = floor(begin * sides) / (F32)sides; + + // pt1 is the first point on the fractional face. + // Starting t and ang values for the first face + t = t_first; + + // Increment to the next point. + // pt2 is the end point on the fractional face + t += t_step; + + t_fraction = (begin - t_first)*sides; + + // Only use if it's not almost exactly on an edge. + if (t_fraction < 0.9999f) + { + np++; + } + + // There's lots of potential here for floating point error to generate unneeded extra points - DJS 04/05/02 + while (t < end) + { + // Iterate through all the integer steps of t. + np++; + + t += t_step; + } + + t_fraction = (end - (t - t_step))*sides; + + // Find the fraction that we need to add to the end point. + t_fraction = (end - (t - t_step))*sides; + if (t_fraction > 0.0001f) + { + np++; + } + + // If we're sliced, the profile is open. + if ((end - begin)*ang_scale < 0.99f) + { + if (params.getHollow() <= 0) + { + // put center point if not hollow. + np++; + } + } + + return np; +} + // What is the bevel parameter used for? - DJS 04/05/02 // Bevel parameter is currently unused but presumedly would support // filleted and chamfered corners @@ -672,6 +736,117 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3 return face; } +//static +S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, + BOOL is_sculpted, S32 sculpt_size) +{ // this is basically LLProfile::generate stripped down to only operations that influence the number of points + LLMemType m1(LLMemType::MTYPE_VOLUME); + + if (detail < MIN_LOD) + { + detail = MIN_LOD; + } + + // Generate the face data + F32 hollow = params.getHollow(); + + S32 np = 0; + + switch (params.getCurveType() & LL_PCODE_PROFILE_MASK) + { + case LL_PCODE_PROFILE_SQUARE: + { + np = getNumNGonPoints(params, 4,-0.375, 0, 1, split); + + if (hollow) + { + np *= 2; + } + } + break; + case LL_PCODE_PROFILE_ISOTRI: + case LL_PCODE_PROFILE_RIGHTTRI: + case LL_PCODE_PROFILE_EQUALTRI: + { + np = getNumNGonPoints(params, 3,0, 0, 1, split); + + if (hollow) + { + np *= 2; + } + } + break; + case LL_PCODE_PROFILE_CIRCLE: + { + // If this has a square hollow, we should adjust the + // number of faces a bit so that the geometry lines up. + U8 hole_type=0; + F32 circle_detail = MIN_DETAIL_FACES * detail; + if (hollow) + { + hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; + if (hole_type == LL_PCODE_HOLE_SQUARE) + { + // Snap to the next multiple of four sides, + // so that corners line up. + circle_detail = llceil(circle_detail / 4.0f) * 4.0f; + } + } + + S32 sides = (S32)circle_detail; + + if (is_sculpted) + sides = sculpt_size; + + np = getNumNGonPoints(params, sides); + + if (hollow) + { + np *= 2; + } + } + break; + case LL_PCODE_PROFILE_CIRCLE_HALF: + { + // If this has a square hollow, we should adjust the + // number of faces a bit so that the geometry lines up. + U8 hole_type=0; + // Number of faces is cut in half because it's only a half-circle. + F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f; + if (hollow) + { + hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK; + if (hole_type == LL_PCODE_HOLE_SQUARE) + { + // Snap to the next multiple of four sides (div 2), + // so that corners line up. + circle_detail = llceil(circle_detail / 2.0f) * 2.0f; + } + } + np = getNumNGonPoints(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f); + + if (hollow) + { + np *= 2; + } + + // Special case for openness of sphere + if ((params.getEnd() - params.getBegin()) < 1.f) + { + } + else if (!hollow) + { + np++; + } + } + break; + default: + break; + }; + + + return np; +} BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, @@ -1133,6 +1308,32 @@ LLPath::~LLPath() { } +S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) +{ //this is basically LLPath::genNGon stripped down to only operations that influence the number of points added + S32 ret = 0; + + F32 step= 1.0f / sides; + F32 t = params.getBegin(); + ret = 1; + + t+=step; + + // Snap to a quantized parameter, so that cut does not + // affect most sample points. + t = ((S32)(t * sides)) / (F32)sides; + + // Run through the non-cut dependent points. + while (t < params.getEnd()) + { + ret++; + t+=step; + } + + ret++; + + return ret; +} + void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) { // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. @@ -1310,6 +1511,56 @@ const LLVector2 LLPathParams::getEndScale() const return end_scale; } +S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) +{ // this is basically LLPath::generate stripped down to only the operations that influence the number of points + LLMemType m1(LLMemType::MTYPE_VOLUME); + + if (detail < MIN_LOD) + { + detail = MIN_LOD; + } + + S32 np = 2; // hardcode for line + + // Is this 0xf0 mask really necessary? DK 03/02/05 + + switch (params.getCurveType() & 0xf0) + { + default: + case LL_PCODE_PATH_LINE: + { + // Take the begin/end twist into account for detail. + np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2; + } + break; + + case LL_PCODE_PATH_CIRCLE: + { + // Increase the detail as the revolutions and twist increase. + F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist()); + + S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions()); + + np = sides; + } + break; + + case LL_PCODE_PATH_CIRCLE2: + { + //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); + np = getNumNGonPoints(params, llfloor(MIN_DETAIL_FACES * detail)); + } + break; + + case LL_PCODE_PATH_TEST: + + np = 5; + break; + }; + + return np; +} + BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { @@ -2159,27 +2410,41 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U32 face_count = mdl.size(); if (face_count == 0) - { - llerrs << "WTF?" << llendl; + { //no faces unpacked, treat as failed decode + llwarns << "found no faces!" << llendl; + return false; } mVolumeFaces.resize(face_count); for (U32 i = 0; i < face_count; ++i) { + LLVolumeFace& face = mVolumeFaces[i]; + + if (mdl[i].has("NoGeometry")) + { //face has no geometry, continue + face.resizeIndices(3); + face.resizeVertices(1); + memset(face.mPositions, 0, sizeof(LLVector4a)); + memset(face.mNormals, 0, sizeof(LLVector4a)); + memset(face.mTexCoords, 0, sizeof(LLVector2)); + memset(face.mIndices, 0, sizeof(U16)*3); + continue; + } + LLSD::Binary pos = mdl[i]["Position"]; LLSD::Binary norm = mdl[i]["Normal"]; LLSD::Binary tc = mdl[i]["TexCoord0"]; LLSD::Binary idx = mdl[i]["TriangleList"]; - LLVolumeFace& face = mVolumeFaces[i]; + //copy out indices face.resizeIndices(idx.size()/2); if (idx.empty() || face.mNumIndices < 3) { //why is there an empty index list? - llerrs <<"WTF?" << llendl; + llwarns <<"Empty face present!" << llendl; continue; } @@ -2377,14 +2642,20 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLVector4a& min = face.mExtents[0]; LLVector4a& max = face.mExtents[1]; - min.clear(); - max.clear(); - min = max = face.mPositions[0]; - - for (S32 i = 1; i < face.mNumVertices; ++i) + if (face.mNumVertices < 3) + { //empty face, use a dummy 1cm (at 1m scale) bounding box + min.splat(-0.005f); + max.splat(0.005f); + } + else { - min.setMin(min, face.mPositions[i]); - max.setMax(max, face.mPositions[i]); + min = max = face.mPositions[0]; + + for (S32 i = 1; i < face.mNumVertices; ++i) + { + min.setMin(min, face.mPositions[i]); + max.setMax(max, face.mPositions[i]); + } } } } @@ -2980,7 +3251,11 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, // don't test lowest LOD to support legacy content DEV-33670 if (mDetail > SCULPT_MIN_AREA_DETAIL) { - if (sculptGetSurfaceArea() < SCULPT_MIN_AREA) + F32 area = sculptGetSurfaceArea(); + + const F32 SCULPT_MAX_AREA = 32.f; + + if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA) { data_is_empty = TRUE; } @@ -4064,6 +4339,23 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const return index; } +void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts) +{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the + //supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost + F32 detail[] = {1.f, 1.5f, 2.5f, 4.f}; + for (S32 i = 0; i < 4; i++) + { + S32 count = 0; + S32 path_points = LLPath::getNumPoints(params.getPathParams(), detail[i]); + S32 profile_points = LLProfile::getNumPoints(params.getProfileParams(), false, detail[i]); + + count = (profile_points-1)*2*(path_points-1); + count += profile_points*2; + + counts[i] = count; + } +} + S32 LLVolume::getNumTriangleIndices() const { BOOL profile_open = getProfile().isOpen(); @@ -5220,6 +5512,8 @@ LLVolumeFace::LLVolumeFace() : mOctree(NULL) { mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); + mExtents[0].splat(-0.5f); + mExtents[1].splat(0.5f); mCenter = mExtents+2; } @@ -5741,6 +6035,11 @@ void LLVolumeFace::cacheOptimize() LLVCacheLRU cache; + if (mNumVertices < 3) + { //nothing to do + return; + } + //mapping of vertices to triangles and indices std::vector<LLVCacheVertexData> vertex_data; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 01bfbd858b..f67f8f644d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -690,6 +690,9 @@ public: BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); } BOOL isOpen() const { return mOpen; } void setDirty() { mDirty = TRUE; } + + static S32 getNumPoints(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, + BOOL is_sculpted = FALSE, S32 sculpt_size = 0); BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, BOOL is_sculpted = FALSE, S32 sculpt_size = 0); BOOL isConcave() const { return mConcave; } @@ -714,6 +717,7 @@ public: protected: void genNormals(const LLProfileParams& params); + static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0); @@ -756,6 +760,9 @@ public: virtual ~LLPath(); + static S32 getNumPoints(const LLPathParams& params, F32 detail); + static S32 getNumNGonPoints(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); + void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE, S32 sculpt_size = 0); @@ -981,6 +988,7 @@ public: // returns number of triangle indeces required for path/profile mesh S32 getNumTriangleIndices() const; + static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts); S32 getNumTriangles() const; diff --git a/indra/llmessage/lldatapacker.h b/indra/llmessage/lldatapacker.h index dd9c4eaa38..b0a638c16e 100644 --- a/indra/llmessage/lldatapacker.h +++ b/indra/llmessage/lldatapacker.h @@ -168,10 +168,15 @@ public: S32 getCurrentSize() const { return (S32)(mCurBufferp - mBufferp); } S32 getBufferSize() const { return mBufferSize; } + const U8* getBuffer() const { return mBufferp; } void reset() { mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); } void freeBuffer() { delete [] mBufferp; mBufferp = mCurBufferp = NULL; mBufferSize = 0; mWriteEnabled = FALSE; } void assignBuffer(U8 *bufferp, S32 size) { + if(mBufferp && mBufferp != bufferp) + { + freeBuffer() ; + } mBufferp = bufferp; mCurBufferp = bufferp; mBufferSize = size; diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 5d03615e53..6133f50637 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -742,6 +742,7 @@ char const* const _PREHASH_MoneyData = LLMessageStringTable::getInstance()->getS char const* const _PREHASH_ObjectDeselect = LLMessageStringTable::getInstance()->getString("ObjectDeselect"); char const* const _PREHASH_NewAssetID = LLMessageStringTable::getInstance()->getString("NewAssetID"); char const* const _PREHASH_ObjectAdd = LLMessageStringTable::getInstance()->getString("ObjectAdd"); +char const* const _PREHASH_SimulatorFeatures = LLMessageStringTable::getInstance()->getString("SimulatorFeatures"); char const* const _PREHASH_RayEndIsIntersection = LLMessageStringTable::getInstance()->getString("RayEndIsIntersection"); char const* const _PREHASH_CompleteAuction = LLMessageStringTable::getInstance()->getString("CompleteAuction"); char const* const _PREHASH_CircuitCode = LLMessageStringTable::getInstance()->getString("CircuitCode"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 8dc86601e6..f94ee1ed22 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -742,6 +742,7 @@ extern char const* const _PREHASH_MoneyData; extern char const* const _PREHASH_ObjectDeselect; extern char const* const _PREHASH_NewAssetID; extern char const* const _PREHASH_ObjectAdd; +extern char const* const _PREHASH_SimulatorFeatures; extern char const* const _PREHASH_RayEndIsIntersection; extern char const* const _PREHASH_CompleteAuction; extern char const* const _PREHASH_CircuitCode; diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h index 0fef596df2..0d149b5258 100644 --- a/indra/llmessage/tests/commtest.h +++ b/indra/llmessage/tests/commtest.h @@ -34,6 +34,7 @@ #include "llsd.h" #include "llhost.h" #include "stringize.h" +#include <map> #include <string> #include <stdexcept> #include <boost/lexical_cast.hpp> @@ -43,6 +44,58 @@ struct CommtestError: public std::runtime_error CommtestError(const std::string& what): std::runtime_error(what) {} }; +static bool query_verbose() +{ + const char* cbose = getenv("INTEGRATION_TEST_VERBOSE"); + if (! cbose) + { + cbose = "1"; + } + std::string strbose(cbose); + return (! (strbose == "0" || strbose == "off" || + strbose == "false" || strbose == "quiet")); +} + +bool verbose() +{ + // This should only be initialized once. + static bool vflag = query_verbose(); + return vflag; +} + +static int query_port(const std::string& var) +{ + const char* cport = getenv(var.c_str()); + if (! cport) + { + throw CommtestError(STRINGIZE("missing environment variable" << var)); + } + // This will throw, too, if the value of PORT isn't numeric. + int port(boost::lexical_cast<int>(cport)); + if (verbose()) + { + std::cout << "getport('" << var << "') = " << port << std::endl; + } + return port; +} + +static int getport(const std::string& var) +{ + typedef std::map<std::string, int> portsmap; + static portsmap ports; + // We can do this with a single map lookup with map::insert(). Either it + // returns an existing entry and 'false' (not newly inserted), or it + // inserts the specified value and 'true'. + std::pair<portsmap::iterator, bool> inserted(ports.insert(portsmap::value_type(var, 0))); + if (inserted.second) + { + // We haven't yet seen this var. Remember its value. + inserted.first->second = query_port(var); + } + // Return the (existing or new) iterator's value. + return inserted.first->second; +} + /** * This struct is shared by a couple of standalone comm tests (ADD_COMM_BUILD_TEST). */ @@ -71,13 +124,10 @@ struct commtest_data static int getport(const std::string& var) { - const char* port = getenv(var.c_str()); - if (! port) - { - throw CommtestError("missing $PORT environment variable"); - } - // This will throw, too, if the value of PORT isn't numeric. - return boost::lexical_cast<int>(port); + // We have a couple consumers of commtest_data::getport(). But we've + // since moved it out to the global namespace. So this is just a + // facade. + return ::getport(var); } bool outcome(const LLSD& _result, bool _success) diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py index cea5032111..9886d49ccc 100644 --- a/indra/llmessage/tests/test_llsdmessage_peer.py +++ b/indra/llmessage/tests/test_llsdmessage_peer.py @@ -38,7 +38,7 @@ mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tes sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) from indra.util.fastest_elementtree import parse as xml_parse from indra.base import llsd -from testrunner import freeport, run, debug +from testrunner import freeport, run, debug, VERBOSE class TestHTTPRequestHandler(BaseHTTPRequestHandler): """This subclass of BaseHTTPRequestHandler is to receive and echo @@ -72,10 +72,10 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler): ## # assuming that the underlying XML parser reads its input file ## # incrementally. Unfortunately I haven't been able to make it work. ## tree = xml_parse(self.rfile) -## debug("Finished raw parse\n") -## debug("parsed XML tree %s\n" % tree) -## debug("parsed root node %s\n" % tree.getroot()) -## debug("root node tag %s\n" % tree.getroot().tag) +## debug("Finished raw parse") +## debug("parsed XML tree %s", tree) +## debug("parsed root node %s", tree.getroot()) +## debug("root node tag %s", tree.getroot().tag) ## return llsd.to_python(tree.getroot()) def do_GET(self): @@ -88,8 +88,10 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler): self.answer(self.read_xml()) def answer(self, data): + debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path) if "fail" not in self.path: response = llsd.format_xml(data.get("reply", llsd.LLSD("success"))) + debug("success: %s", response) self.send_response(200) self.send_header("Content-type", "application/llsd+xml") self.send_header("Content-Length", str(len(response))) @@ -106,16 +108,21 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler): ("fail requested", "Your request specified failure status %s " "without providing a reason" % status))[1]) + debug("fail requested: %s: %r", status, reason) self.send_error(status, reason) - def log_request(self, code, size=None): - # For present purposes, we don't want the request splattered onto - # stderr, as it would upset devs watching the test run - pass + if not VERBOSE: + # When VERBOSE is set, skip both these overrides because they exist to + # suppress output. - def log_error(self, format, *args): - # Suppress error output as well - pass + def log_request(self, code, size=None): + # For present purposes, we don't want the request splattered onto + # stderr, as it would upset devs watching the test run + pass + + def log_error(self, format, *args): + # Suppress error output as well + pass if __name__ == "__main__": # Instantiate an HTTPServer(TestHTTPRequestHandler) on the first free port @@ -130,4 +137,5 @@ if __name__ == "__main__": # command-line parsing -- and anyway, for C++ integration tests, that's # performed in TUT code rather than our own. os.environ["PORT"] = str(port) + debug("$PORT = %s", port) sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:])) diff --git a/indra/llmessage/tests/testrunner.py b/indra/llmessage/tests/testrunner.py index 8ff13e0426..f329ec2a0e 100644 --- a/indra/llmessage/tests/testrunner.py +++ b/indra/llmessage/tests/testrunner.py @@ -29,14 +29,21 @@ $/LicenseInfo$ import os import sys +import re import errno import socket -def debug(*args): - sys.stdout.writelines(args) - sys.stdout.flush() -# comment out the line below to enable debug output -debug = lambda *args: None +VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "1") # default to verbose +# Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if +# that construct actually turns on verbosity... +VERBOSE = not re.match(r"(0|off|false|quiet)$", VERBOSE, re.IGNORECASE) + +if VERBOSE: + def debug(fmt, *args): + print fmt % args + sys.stdout.flush() +else: + debug = lambda *args: None def freeport(portlist, expr): """ @@ -78,44 +85,53 @@ def freeport(portlist, expr): # pass 'port' to client code # call server.serve_forever() """ - # If portlist is completely empty, let StopIteration propagate: that's an - # error because we can't return meaningful values. We have no 'port', - # therefore no 'expr(port)'. - portiter = iter(portlist) - port = portiter.next() - - while True: - try: - # If this value of port works, return as promised. - return expr(port), port - - except socket.error, err: - # Anything other than 'Address already in use', propagate - if err.args[0] != errno.EADDRINUSE: - raise - - # Here we want the next port from portiter. But on StopIteration, - # we want to raise the original exception rather than - # StopIteration. So save the original exc_info(). - type, value, tb = sys.exc_info() + try: + # If portlist is completely empty, let StopIteration propagate: that's an + # error because we can't return meaningful values. We have no 'port', + # therefore no 'expr(port)'. + portiter = iter(portlist) + port = portiter.next() + + while True: try: + # If this value of port works, return as promised. + value = expr(port) + + except socket.error, err: + # Anything other than 'Address already in use', propagate + if err.args[0] != errno.EADDRINUSE: + raise + + # Here we want the next port from portiter. But on StopIteration, + # we want to raise the original exception rather than + # StopIteration. So save the original exc_info(). + type, value, tb = sys.exc_info() try: - port = portiter.next() - except StopIteration: - raise type, value, tb - finally: - # Clean up local traceback, see docs for sys.exc_info() - del tb - - # Recap of the control flow above: - # If expr(port) doesn't raise, return as promised. - # If expr(port) raises anything but EADDRINUSE, propagate that - # exception. - # If portiter.next() raises StopIteration -- that is, if the port - # value we just passed to expr(port) was the last available -- reraise - # the EADDRINUSE exception. - # If we've actually arrived at this point, portiter.next() delivered a - # new port value. Loop back to pass that to expr(port). + try: + port = portiter.next() + except StopIteration: + raise type, value, tb + finally: + # Clean up local traceback, see docs for sys.exc_info() + del tb + + else: + debug("freeport() returning %s on port %s", value, port) + return value, port + + # Recap of the control flow above: + # If expr(port) doesn't raise, return as promised. + # If expr(port) raises anything but EADDRINUSE, propagate that + # exception. + # If portiter.next() raises StopIteration -- that is, if the port + # value we just passed to expr(port) was the last available -- reraise + # the EADDRINUSE exception. + # If we've actually arrived at this point, portiter.next() delivered a + # new port value. Loop back to pass that to expr(port). + + except Exception, err: + debug("*** freeport() raising %s: %s", err.__class__.__name__, err) + raise def run(*args, **kwds): """All positional arguments collectively form a command line, executed as @@ -144,8 +160,7 @@ def run(*args, **kwds): # - [no p] don't use the PATH because we specifically want to invoke the # executable passed as our first arg, # - [no e] child should inherit this process's environment. - debug("Running %s...\n" % (" ".join(args))) - sys.stdout.flush() + debug("Running %s...", " ".join(args)) rc = os.spawnv(os.P_WAIT, args[0], args) - debug("%s returned %s\n" % (args[0], rc)) + debug("%s returned %s", args[0], rc) return rc diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 2103216536..9f666369d4 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -436,6 +436,107 @@ std::string LLPluginClassMedia::translateModifiers(MASK modifiers) return result; } +void LLPluginClassMedia::jsExposeObjectEvent( bool expose ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_expose_object"); + message.setValueBoolean( "expose", expose ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsValuesValidEvent( bool valid ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_values_valid"); + message.setValueBoolean( "valid", valid ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentLocationEvent( double x, double y, double z ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_location"); + message.setValueReal( "x", x ); + message.setValueReal( "y", y ); + message.setValueReal( "z", z ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentGlobalLocationEvent( double x, double y, double z ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_global_location"); + message.setValueReal( "x", x ); + message.setValueReal( "y", y ); + message.setValueReal( "z", z ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentOrientationEvent( double angle ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_orientation"); + message.setValueReal( "angle", angle ); + + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentLanguageEvent( const std::string& language ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_language"); + message.setValue( "language", language ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentRegionEvent( const std::string& region ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_region"); + message.setValue( "region", region ); + sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentMaturityEvent( const std::string& maturity ) +{ + if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) + { + return; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_maturity"); + message.setValue( "maturity", maturity ); + sendMessage( message ); +} + void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers) { if(type == MOUSE_EVENT_MOVE) diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index cf8d8b26b9..fea836aa68 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -117,7 +117,17 @@ public: bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data); void scrollEvent(int x, int y, MASK modifiers); - + + // Javascript <-> viewer events + void jsExposeObjectEvent( bool expose ); + void jsValuesValidEvent( bool valid ); + void jsAgentLocationEvent( double x, double y, double z ); + void jsAgentGlobalLocationEvent( double x, double y, double z ); + void jsAgentOrientationEvent( double angle ); + void jsAgentLanguageEvent( const std::string& language ); + void jsAgentRegionEvent( const std::string& region_name ); + void jsAgentMaturityEvent( const std::string& maturity ); + // Text may be unicode (utf8 encoded) bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 794cdb83d5..0463d5364b 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -50,7 +50,7 @@ std::string model_names[] = "low_lod", "medium_lod", "high_lod", - "physics_shape" + "physics_mesh" }; const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); @@ -84,7 +84,7 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr domInputLocal_Array& v_inp = vertices->getInput_array(); if (inputs[j]->getOffset() != 0) { - llerrs << "WTF?" << llendl; + llerrs << "Vertex array offset MUST be zero." << llendl; } for (U32 k = 0; k < v_inp.getCount(); ++k) @@ -98,7 +98,7 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr if (src->getTechnique_common()->getAccessor()->getStride() != 3) { - llerrs << "WTF?" << llendl; + llerrs << "Vertex array stride MUST be three." << llendl; } domListOfFloats& v = src->getFloat_array()->getValue(); @@ -149,9 +149,10 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr } } -void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride, +bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride, domSource* &pos_source, domSource* &tc_source, domSource* &norm_source) { + idx_stride = 0; for (U32 j = 0; j < inputs.getCount(); ++j) @@ -163,7 +164,11 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S const domURIFragmentType& uri = inputs[j]->getSource(); daeElementRef elem = uri.getElement(); domVertices* vertices = (domVertices*) elem.cast(); - + if ( !vertices ) + { + return false; + } + domInputLocal_Array& v_inp = vertices->getInput_array(); @@ -207,6 +212,8 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S } idx_stride += 1; + + return true; } LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domTrianglesRef& tri) @@ -227,8 +234,12 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa S32 idx_stride = 0; - get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source); + if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source ) + { + return LLModel::BAD_ELEMENT; + } + domPRef p = tri->getP(); domListOfUInts& idx = p->getValue(); @@ -367,7 +378,10 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac S32 idx_stride = 0; - get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source); + if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source)) + { + return LLModel::BAD_ELEMENT; + } LLVolumeFace face; @@ -564,7 +578,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domURIFragmentType& uri = inputs[i]->getSource(); daeElementRef elem = uri.getElement(); domVertices* vertices = (domVertices*) elem.cast(); - + if (!vertices) + { + return LLModel::BAD_ELEMENT; + } domInputLocal_Array& v_inp = vertices->getInput_array(); for (U32 k = 0; k < v_inp.getCount(); ++k) @@ -574,6 +591,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domURIFragmentType& uri = v_inp[k]->getSource(); daeElementRef elem = uri.getElement(); domSource* src = (domSource*) elem.cast(); + if (!src) + { + return LLModel::BAD_ELEMENT; + } v = &(src->getFloat_array()->getValue()); } } @@ -585,6 +606,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domURIFragmentType& uri = inputs[i]->getSource(); daeElementRef elem = uri.getElement(); domSource* src = (domSource*) elem.cast(); + if (!src) + { + return LLModel::BAD_ELEMENT; + } n = &(src->getFloat_array()->getValue()); } else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0) @@ -593,6 +618,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domURIFragmentType& uri = inputs[i]->getSource(); daeElementRef elem = uri.getElement(); domSource* src = (domSource*) elem.cast(); + if (!src) + { + return LLModel::BAD_ELEMENT; + } t = &(src->getFloat_array()->getValue()); } } @@ -667,11 +696,6 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac } } - if (cur_idx != vert_idx.size()) - { - llerrs << "WTF?" << llendl; - } - //build vertex array from map std::vector<LLVolumeFace::VertexData> new_verts; new_verts.resize(vert_idx.size()); @@ -717,7 +741,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac //static std::string LLModel::getStatusString(U32 status) { - const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow"}; + const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"}; if(status < INVALID_STATUS) { @@ -755,7 +779,6 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh) for (U32 i = 0; i < polys.getCount(); ++i) { domPolylistRef& poly = polys.get(i); - mStatus = load_face_from_dom_polylist(mVolumeFaces, mMaterialList, poly); if(mStatus != NO_ERRORS) @@ -765,12 +788,12 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh) return ; //abort } } - + domPolygons_Array& polygons = mesh->getPolygons_array(); + for (U32 i = 0; i < polygons.getCount(); ++i) { domPolygonsRef& poly = polygons.get(i); - mStatus = load_face_from_dom_polygons(mVolumeFaces, mMaterialList, poly); if(mStatus != NO_ERRORS) @@ -780,7 +803,7 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh) return ; //abort } } - + } BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh) @@ -926,11 +949,6 @@ void LLModel::normalizeVolumeFaces() { LLVector4a min, max; - if (mVolumeFaces[0].mNumVertices <= 0) - { - llerrs << "WTF?" << llendl; - } - // For all of the volume faces // in the model, loop over // them and see what the extents @@ -942,11 +960,6 @@ void LLModel::normalizeVolumeFaces() { LLVolumeFace& face = mVolumeFaces[i]; - if (face.mNumVertices <= 0) - { - llerrs << "WTF?" << llendl; - } - update_min_max(min, max, face.mExtents[0]); update_min_max(min, max, face.mExtents[1]); } @@ -991,6 +1004,9 @@ void LLModel::normalizeVolumeFaces() scale.splat(1.f); scale.div(size); + LLVector4a inv_scale(1.f); + inv_scale.div(scale); + for (U32 i = 0; i < mVolumeFaces.size(); ++i) { LLVolumeFace& face = mVolumeFaces[i]; @@ -1007,10 +1023,14 @@ void LLModel::normalizeVolumeFaces() // For all the positions, we scale // the positions to fit within the unit cube. LLVector4a* pos = (LLVector4a*) face.mPositions; + LLVector4a* norm = (LLVector4a*) face.mNormals; + for (U32 j = 0; j < face.mNumVertices; ++j) { pos[j].add(trans); pos[j].mul(scale); + norm[j].mul(inv_scale); + norm[j].normalize3(); } } @@ -1282,11 +1302,6 @@ void LLModel::generateNormals(F32 angle_cutoff) { LLVector4a& n = iter->second[k].getNormal(); - if (!iter->second[k].getPosition().equals3(new_face.mPositions[i])) - { - llerrs << "WTF?" << llendl; - } - F32 cur = n.dot3(ref_norm).getF32(); if (cur > best) @@ -1403,7 +1418,11 @@ LLSD LLModel::writeModel( if (!decomp.mBaseHull.empty() || !decomp.mHull.empty()) { - mdl["decomposition"] = decomp.asLLSD(); + mdl["physics_convex"] = decomp.asLLSD(); + if (!decomp.mHull.empty()) + { //convex decomposition exists, physics mesh will not be used + model[LLModel::LOD_PHYSICS] = NULL; + } } for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx) @@ -1428,8 +1447,9 @@ LLSD LLModel::writeModel( for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i) { //for each face const LLVolumeFace& face = model[idx]->getVolumeFace(i); - if (!face.mNumVertices) + if (face.mNumVertices < 3) { //don't export an empty face + mdl[model_names[idx]][i]["NoGeometry"] = true; continue; } LLSD::Binary verts(face.mNumVertices*3*2); @@ -1462,7 +1482,6 @@ LLSD LLModel::writeModel( //position + normal for (U32 k = 0; k < 3; ++k) { //for each component - //convert to 16-bit normalized across domain U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535); @@ -1506,7 +1525,6 @@ LLSD LLModel::writeModel( //write out face data mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); - mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue(); @@ -1532,11 +1550,6 @@ LLSD LLModel::writeModel( weight_list& weights = high->getJointInfluences(pos); - if (weights.size() > 4) - { - llerrs << "WTF?" << llendl; - } - S32 count = 0; for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) { @@ -1600,23 +1613,19 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite) cur_offset += size; bytes += size; } - else - { - llerrs << "WTF?" << llendl; - } } std::string decomposition; - if (mdl.has("decomposition")) + if (mdl.has("physics_convex")) { //write out convex decomposition - decomposition = zip_llsd(mdl["decomposition"]); + decomposition = zip_llsd(mdl["physics_convex"]); U32 size = decomposition.size(); if (size > 0) { - header["decomposition"]["offset"] = (LLSD::Integer) cur_offset; - header["decomposition"]["size"] = (LLSD::Integer) size; + header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset; + header["physics_convex"]["size"] = (LLSD::Integer) size; cur_offset += size; bytes += size; } @@ -1637,11 +1646,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite) cur_offset += size; bytes += size; } - else - { - header[model_names[i]]["offset"] = -1; - header[model_names[i]]["size"] = 0; - } } if (!nowrite) @@ -1655,7 +1659,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite) if (!decomposition.empty()) { //write decomposition block - ostr.write((const char*) decomposition.data(), header["decomposition"]["size"].asInteger()); + ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger()); } for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++) @@ -1678,7 +1682,7 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) { if ((iter->first - pos).magVec() > 0.1f) { - llerrs << "WTF?" << llendl; + llerrs << "Couldn't find weight list." << llendl; } return iter->second; @@ -1771,7 +1775,7 @@ void LLModel::updateHullCenters() if (mHullPoints > 0) { mCenterOfHullCenters *= 1.f / mHullPoints; - llassert(mPhysics.asLLSD().has("HullList")); + llassert(mPhysics.hasHullList()); } } @@ -1794,7 +1798,7 @@ bool LLModel::loadModel(std::istream& is) "low_lod", "medium_lod", "high_lod", - "physics_shape", + "physics_mesh", }; const S32 MODEL_LODS = 5; @@ -1893,8 +1897,8 @@ bool LLModel::loadSkinInfo(LLSD& header, std::istream &is) bool LLModel::loadDecomposition(LLSD& header, std::istream& is) { - S32 offset = header["decomposition"]["offset"].asInteger(); - S32 size = header["decomposition"]["size"].asInteger(); + S32 offset = header["physics_convex"]["offset"].asInteger(); + S32 size = header["physics_convex"]["size"].asInteger(); if (offset >= 0 && size > 0) { @@ -2034,7 +2038,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) { // updated for const-correctness. gcc is picky about this type of thing - Nyx const LLSD::Binary& hulls = decomp["HullList"].asBinary(); - const LLSD::Binary& position = decomp["Position"].asBinary(); + const LLSD::Binary& position = decomp["Positions"].asBinary(); U16* p = (U16*) &position[0]; @@ -2044,11 +2048,19 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) LLVector3 max; LLVector3 range; - min.setValue(decomp["Min"]); - max.setValue(decomp["Max"]); + if (decomp.has("Min")) + { + min.setValue(decomp["Min"]); + max.setValue(decomp["Max"]); + } + else + { + min.set(-0.5f, -0.5f, -0.5f); + max.set(0.5f, 0.5f, 0.5f); + } + range = max-min; - for (U32 i = 0; i < hulls.size(); ++i) { U16 count = (hulls[i] == 0) ? 256 : hulls[i]; @@ -2064,6 +2076,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) //point must be unique //llassert(valid.find(test) == valid.end()); valid.insert(test); + mHull[i].push_back(LLVector3( (F32) p[0]/65535.f*range.mV[0]+min.mV[0], (F32) p[1]/65535.f*range.mV[1]+min.mV[1], @@ -2078,9 +2091,9 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) } } - if (decomp.has("Hull")) + if (decomp.has("BoundingVerts")) { - const LLSD::Binary& position = decomp["Hull"].asBinary(); + const LLSD::Binary& position = decomp["BoundingVerts"].asBinary(); U16* p = (U16*) &position[0]; @@ -2116,10 +2129,15 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) { //empty base hull mesh to indicate decomposition has been loaded //but contains no base hull - mBaseHullMesh.clear();; + mBaseHullMesh.clear(); } } +bool LLModel::Decomposition::hasHullList() const +{ + return !mHull.empty() ; +} + LLSD LLModel::Decomposition::asLLSD() const { LLSD ret; @@ -2130,11 +2148,9 @@ LLSD LLModel::Decomposition::asLLSD() const } //write decomposition block - // ["decomposition"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points - // ["decomposition"]["PositionDomain"]["Min"/"Max"] - // ["decomposition"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points - // ["decomposition"]["Hull"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape - + // ["physics_convex"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points + // ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points + // ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape //get minimum and maximum LLVector3 min; @@ -2183,6 +2199,8 @@ LLSD LLModel::Decomposition::asLLSD() const { LLSD::Binary p(total*3*2); + LLVector3 min(-0.5f, -0.5f, -0.5f); + LLVector3 max(0.5f, 0.5f, 0.5f); LLVector3 range = max-min; U32 vert_idx = 0; @@ -2198,17 +2216,24 @@ LLSD LLModel::Decomposition::asLLSD() const U64 test = 0; for (U32 k = 0; k < 3; k++) { + F32* src = (F32*) (mHull[i][j].mV); + + llassert(src[k] <= 0.501f && src[k] >= -0.501f); + //convert to 16-bit normalized across domain - U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535); + U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535); - switch (k) + if(valid.size() < 3) { - case 0: test = test | (U64) val; break; - case 1: test = test | ((U64) val << 16); break; - case 2: test = test | ((U64) val << 32); break; - }; + switch (k) + { + case 0: test = test | (U64) val; break; + case 1: test = test | ((U64) val << 16); break; + case 2: test = test | ((U64) val << 32); break; + }; - valid.insert(test); + valid.insert(test); + } U8* buff = (U8*) &val; //write to binary buffer @@ -2220,17 +2245,21 @@ LLSD LLModel::Decomposition::asLLSD() const } } - //must have at least 4 unique points - llassert(valid.size() > 3); + //must have at least 3 unique points + llassert(valid.size() > 2); } - ret["Position"] = p; + ret["Positions"] = p; } + //llassert(!mBaseHull.empty()); + if (!mBaseHull.empty()) { LLSD::Binary p(mBaseHull.size()*3*2); + LLVector3 min(-0.5f, -0.5f, -0.5f); + LLVector3 max(0.5f, 0.5f, 0.5f); LLVector3 range = max-min; U32 vert_idx = 0; @@ -2238,6 +2267,8 @@ LLSD LLModel::Decomposition::asLLSD() const { for (U32 k = 0; k < 3; k++) { + llassert(mBaseHull[j].mV[k] <= 0.51f && mBaseHull[j].mV[k] >= -0.51f); + //convert to 16-bit normalized across domain U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535); @@ -2248,12 +2279,12 @@ LLSD LLModel::Decomposition::asLLSD() const if (vert_idx > p.size()) { - llerrs << "WTF?" << llendl; + llerrs << "Index out of bounds" << llendl; } } } - ret["Hull"] = p; + ret["BoundingVerts"] = p; } return ret; @@ -2283,10 +2314,5 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs) { //take physics shape mesh from rhs mPhysicsShapeMesh = rhs->mPhysicsShapeMesh; } - - if (!mHull.empty()) - { //verify - llassert(asLLSD().has("HullList")); - } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 23f4b5cb42..cd9f76fcb7 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -73,6 +73,7 @@ public: { NO_ERRORS = 0, VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535. + BAD_ELEMENT, INVALID_STATUS } ; @@ -106,6 +107,7 @@ public: Decomposition(LLSD& data); void fromLLSD(LLSD& data); LLSD asLLSD() const; + bool hasHullList() const; void merge(const Decomposition* rhs); diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index d6a31dc862..180ae4dfa6 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -554,7 +554,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch BOOL in_word = FALSE; // avoid S32 overflow when max_pixels == S32_MAX by staying in floating point - F32 scaled_max_pixels = ceil(max_pixels * sScaleX); + F32 scaled_max_pixels = max_pixels * sScaleX; F32 width_padding = 0.f; LLFontGlyphInfo* next_glyph = NULL; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index f29ee0e57e..a3aed4dd8a 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -127,6 +127,11 @@ PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL; PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL; PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL; +// GL_ARB_map_buffer_range +PFNGLMAPBUFFERRANGEPROC glMapBufferRange; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; + + // vertex object prototypes PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI = NULL; PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI = NULL; @@ -178,6 +183,12 @@ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL; PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL; PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL; +//GL_ARB_texture_multisample +PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +PFNGLSAMPLEMASKIPROC glSampleMaski; + // GL_EXT_blend_func_separate PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL; @@ -321,18 +332,26 @@ LLGLManager::LLGLManager() : mHasMipMapGeneration(FALSE), mHasCompressedTextures(FALSE), mHasFramebufferObject(FALSE), + mMaxSamples(0), mHasBlendFuncSeparate(FALSE), mHasVertexBufferObject(FALSE), + mHasMapBufferRange(FALSE), mHasPBuffer(FALSE), mHasShaderObjects(FALSE), mHasVertexShader(FALSE), mHasFragmentShader(FALSE), + mNumTextureImageUnits(0), mHasOcclusionQuery(FALSE), mHasOcclusionQuery2(FALSE), mHasPointParameters(FALSE), mHasDrawBuffers(FALSE), mHasTextureRectangle(FALSE), + mHasTextureMultisample(FALSE), + mMaxSampleMaskWords(0), + mMaxColorTextureSamples(0), + mMaxDepthTextureSamples(0), + mMaxIntegerSamples(0), mHasAnisotropic(FALSE), mHasARBEnvCombine(FALSE), @@ -534,6 +553,26 @@ bool LLGLManager::initGL() return false; } + if (mHasFragmentShader) + { + GLint num_tex_image_units; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units); + mNumTextureImageUnits = llmin(num_tex_image_units, 32); + } + + if (mHasTextureMultisample) + { + glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); + glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); + glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); + glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); + } + + if (mHasFramebufferObject) + { + glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); + } + setToDebugGPU(); initGLStates(); @@ -640,6 +679,14 @@ std::string LLGLManager::getRawGLString() return gl_string; } +U32 LLGLManager::getNumFBOFSAASamples(U32 samples) +{ + samples = llmin(samples, (U32) mMaxColorTextureSamples); + samples = llmin(samples, (U32) mMaxDepthTextureSamples); + samples = llmin(samples, (U32) 4); + return samples; +} + void LLGLManager::shutdownGL() { if (mInited) @@ -720,6 +767,7 @@ void LLGLManager::initExtensions() 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); + mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", 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 #ifdef GL_ARB_framebuffer_object @@ -734,6 +782,7 @@ void LLGLManager::initExtensions() mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); + mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts); #if !LL_DARWIN mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); #endif @@ -878,11 +927,13 @@ void LLGLManager::initExtensions() LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL; mHasMipMapGeneration = FALSE; } +#if !LL_DARWIN if (mIsATI && mHasMipMapGeneration) { LL_INFOS("RenderInit") << "Disabling mip-map generation for ATI GPUs (performance opt)" << LL_ENDL; mHasMipMapGeneration = FALSE; } +#endif // Misc glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange); @@ -911,6 +962,11 @@ void LLGLManager::initExtensions() mHasVertexBufferObject = FALSE; } } + if (mHasMapBufferRange) + { + glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange"); + glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glFlushMappedBufferRange"); + } if (mHasFramebufferObject) { llinfos << "initExtensions() FramebufferObject-related procs..." << llendl; @@ -943,6 +999,13 @@ void LLGLManager::initExtensions() { glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT"); } + if (mHasTextureMultisample) + { + glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample"); + glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample"); + glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv"); + glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski"); + } #if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS // This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements"); @@ -1360,10 +1423,6 @@ void LLGLState::checkTextureChannels(const std::string& msg) } } - GLint maxTextureUnits = 0; - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); - stop_glerror(); - static const char* label[] = { "GL_TEXTURE_2D", @@ -1374,7 +1433,8 @@ void LLGLState::checkTextureChannels(const std::string& msg) "GL_TEXTURE_GEN_T", "GL_TEXTURE_GEN_Q", "GL_TEXTURE_GEN_R", - "GL_TEXTURE_RECTANGLE_ARB" + "GL_TEXTURE_RECTANGLE_ARB", + "GL_TEXTURE_2D_MULTISAMPLE" }; static GLint value[] = @@ -1387,7 +1447,8 @@ void LLGLState::checkTextureChannels(const std::string& msg) GL_TEXTURE_GEN_T, GL_TEXTURE_GEN_Q, GL_TEXTURE_GEN_R, - GL_TEXTURE_RECTANGLE_ARB + GL_TEXTURE_RECTANGLE_ARB, + GL_TEXTURE_2D_MULTISAMPLE }; GLint stackDepth = 0; @@ -1396,68 +1457,96 @@ void LLGLState::checkTextureChannels(const std::string& msg) glh::matrix4f identity; identity.identity(); - for (GLint i = 1; i < maxTextureUnits; i++) + for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++) { gGL.getTexUnit(i)->activate(); - glClientActiveTextureARB(GL_TEXTURE0_ARB+i); - stop_glerror(); - glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth); - stop_glerror(); - if (stackDepth != 1) + if (i < gGLManager.mNumTextureUnits) { - error = TRUE; - LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL; + glClientActiveTextureARB(GL_TEXTURE0_ARB+i); + stop_glerror(); + glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth); + stop_glerror(); - if (gDebugSession) + if (stackDepth != 1) { - gFailLog << "Texture matrix stack corrupted." << std::endl; + error = TRUE; + LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL; + + if (gDebugSession) + { + gFailLog << "Texture matrix stack corrupted." << std::endl; + } } - } - glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m); - stop_glerror(); + glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m); + stop_glerror(); - if (mat != identity) - { - error = TRUE; - LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL; - if (gDebugSession) + if (mat != identity) + { + error = TRUE; + LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL; + if (gDebugSession) + { + gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl; + } + } + + for (S32 j = (i == 0 ? 1 : 0); + j < 9; j++) { - gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl; + if (j == 8 && !gGLManager.mHasTextureRectangle || + j == 9 && !gGLManager.mHasTextureMultisample) + { + continue; + } + + if (glIsEnabled(value[j])) + { + error = TRUE; + LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL; + if (gDebugSession) + { + gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl; + } + } + stop_glerror(); } - } - - for (S32 j = (i == 0 ? 1 : 0); - j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++) - { - if (glIsEnabled(value[j])) + glGetFloatv(GL_TEXTURE_MATRIX, mat.m); + stop_glerror(); + + if (mat != identity) { error = TRUE; - LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL; + LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL; if (gDebugSession) { - gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl; + gFailLog << "Texture matrix " << i << " is not identity." << std::endl; } } - stop_glerror(); } - glGetFloatv(GL_TEXTURE_MATRIX, mat.m); - stop_glerror(); - - if (mat != identity) { - error = TRUE; - LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL; - if (gDebugSession) + GLint tex = 0; + stop_glerror(); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex); + stop_glerror(); + + if (tex != 0) { - gFailLog << "Texture matrix " << i << " is not identity." << std::endl; + error = TRUE; + LL_WARNS("RenderState") << "Texture channel " << i << " still has texture " << tex << " bound." << llendl; + + if (gDebugSession) + { + gFailLog << "Texture channel " << i << " still has texture " << tex << " bound." << std::endl; + } } } } + stop_glerror(); gGL.getTexUnit(0)->activate(); glClientActiveTextureARB(GL_TEXTURE0_ARB); stop_glerror(); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 3d002fd8c4..d1bee00161 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -83,20 +83,28 @@ public: BOOL mHasMipMapGeneration; BOOL mHasCompressedTextures; BOOL mHasFramebufferObject; + S32 mMaxSamples; BOOL mHasBlendFuncSeparate; - + // ARB Extensions BOOL mHasVertexBufferObject; + BOOL mHasMapBufferRange; BOOL mHasPBuffer; BOOL mHasShaderObjects; BOOL mHasVertexShader; BOOL mHasFragmentShader; + S32 mNumTextureImageUnits; BOOL mHasOcclusionQuery; BOOL mHasOcclusionQuery2; BOOL mHasPointParameters; BOOL mHasDrawBuffers; BOOL mHasDepthClamp; BOOL mHasTextureRectangle; + BOOL mHasTextureMultisample; + S32 mMaxSampleMaskWords; + S32 mMaxColorTextureSamples; + S32 mMaxDepthTextureSamples; + S32 mMaxIntegerSamples; // Other extensions. BOOL mHasAnisotropic; @@ -138,6 +146,7 @@ public: void printGLInfoString(); void getGLInfo(LLSD& info); + U32 getNumFBOFSAASamples(U32 desired_samples = 32); // In ALL CAPS std::string mGLVendor; std::string mGLVendorShort; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index d8140a124d..f35f329f00 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -68,6 +68,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB; extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB; extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB; +// GL_ARB_map_buffer_range +extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; +extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; + // GL_ATI_vertex_array_object extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI; extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI; @@ -306,6 +310,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB; extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB; extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB; +// GL_ARB_map_buffer_range +extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; +extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; + // GL_ATI_vertex_array_object extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI; extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI; @@ -474,6 +482,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; //GL_ARB_draw_buffers extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; +//GL_ARB_texture_multisample +extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +extern PFNGLSAMPLEMASKIPROC glSampleMaski; #elif LL_WINDOWS //---------------------------------------------------------------------------- @@ -506,6 +519,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB; extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB; extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB; +// GL_ARB_map_buffer_range +extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; +extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; + // GL_ATI_vertex_array_object extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI; extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI; @@ -673,6 +690,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; //GL_ARB_draw_buffers extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; +//GL_ARB_texture_multisample +extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +extern PFNGLSAMPLEMASKIPROC glSampleMaski; #elif LL_DARWIN //---------------------------------------------------------------------------- @@ -714,13 +736,55 @@ extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_A #ifndef GL_ARB_framebuffer_object #define glGenerateMipmap glGenerateMipmapEXT +#define GL_MAX_SAMPLES 0x8D57 #endif + // GL_ARB_draw_buffers extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; #ifdef __cplusplus extern "C" { #endif + +// +// Define map buffer range headers on Mac +// +#ifndef GL_ARB_map_buffer_range +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#endif + +// +// Define multisample headers on Mac +// +#ifndef GL_ARB_texture_multisample +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#endif + // // Define vertex buffer object headers on Mac // @@ -757,7 +821,7 @@ extern "C" { #define GL_DYNAMIC_READ_ARB 0x88E9 #define GL_DYNAMIC_COPY_ARB 0x88EA #endif - + #ifndef GL_ARB_vertex_buffer_object diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 257bcd9380..8e99f62de6 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -48,6 +48,8 @@ using std::pair; using std::make_pair; using std::string; +GLhandleARB LLGLSLShader::sCurBoundShader = 0; + BOOL shouldChange(const LLVector4& v1, const LLVector4& v2) { return v1 != v2; @@ -56,7 +58,7 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2) LLShaderFeatures::LLShaderFeatures() : calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false), hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false), -hasGamma(false), hasLighting(false), calculatesAtmospherics(false) +hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false) { } @@ -107,16 +109,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes, // Create program mProgramObject = glCreateProgramObjectARB(); - // Attach existing objects - if (!LLShaderMgr::instance()->attachShaderFeatures(this)) - { - return FALSE; - } - + //compile new source vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin(); for ( ; fileIter != mShaderFiles.end(); fileIter++ ) { - GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second); + GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels); LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; if (shaderhandle > 0) { @@ -128,6 +125,12 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes, } } + // Attach existing objects + if (!LLShaderMgr::instance()->attachShaderFeatures(this)) + { + return FALSE; + } + // Map attributes and uniforms if (success) { @@ -149,6 +152,29 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes, return createShader(attributes,uniforms); } } + else if (mFeatures.mIndexedTextureChannels > 0) + { //override texture channels for indexed texture rendering + bind(); + S32 channel_count = mFeatures.mIndexedTextureChannels; + + for (S32 i = 0; i < channel_count; i++) + { + uniform1i(llformat("tex%d", i), i); + } + + S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten + for (U32 i = 0; i < mTexture.size(); i++) + { + if (mTexture[i] > -1 && mTexture[i] < channel_count) + { + llassert(cur_tex < gGLManager.mNumTextureImageUnits); + uniform1i(i, cur_tex); + mTexture[i] = cur_tex++; + } + } + unbind(); + } + return success; } @@ -293,7 +319,8 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms) GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) { - if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) + if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB || + type == GL_SAMPLER_2D_MULTISAMPLE) { //this here is a texture glUniform1iARB(location, mActiveTextureChannels); LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; @@ -342,7 +369,7 @@ void LLGLSLShader::bind() if (gGLManager.mHasShaderObjects) { glUseProgramObjectARB(mProgramObject); - + sCurBoundShader = mProgramObject; if (mUniformsDirty) { LLShaderMgr::instance()->updateShaderUniforms(this); @@ -365,6 +392,7 @@ void LLGLSLShader::unbind() } } glUseProgramObjectARB(0); + sCurBoundShader = 0; stop_glerror(); } } @@ -372,6 +400,7 @@ void LLGLSLShader::unbind() void LLGLSLShader::bindNoShader(void) { glUseProgramObjectARB(0); + sCurBoundShader = 0; } S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index d46ddbbe18..4922eb6d67 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -45,6 +45,8 @@ public: bool hasObjectSkinning; bool hasAtmospherics; bool hasGamma; + S32 mIndexedTextureChannels; + bool disableTextureIndex; // char numLights; @@ -64,6 +66,8 @@ public: LLGLSLShader(); + static GLhandleARB sCurBoundShader; + void unload(); BOOL createShader(std::vector<std::string> * attributes, std::vector<std::string> * uniforms); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index d408077c68..60a5962234 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1083,12 +1083,17 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures) } // static -void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) +void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate) { for (S32 i = 0; i < numTextures; i++) { sDeadTextureList.push_back(textures[i]); } + + if (immediate) + { + LLImageGL::deleteDeadTextures(); + } } // static @@ -1413,11 +1418,13 @@ void LLImageGL::deleteDeadTextures() { GLuint tex = sDeadTextureList.front(); sDeadTextureList.pop_front(); - for (int i = 0; i < gGLManager.mNumTextureUnits; i++) + for (int i = 0; i < gGLManager.mNumTextureImageUnits; i++) { - if (sCurrentBoundTextures[i] == tex) + LLTexUnit* tex_unit = gGL.getTexUnit(i); + + if (tex_unit->getCurrTexture() == tex) { - gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE); + tex_unit->unbind(tex_unit->getCurrType()); stop_glerror(); } } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 6c980984c0..2cfb15b0d9 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -98,7 +98,7 @@ public: // These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D() // for tracking purposes and will be deprecated in the future static void generateTextures(S32 numTextures, U32 *textures); - static void deleteTextures(S32 numTextures, U32 *textures); + static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false); static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels); BOOL createGLTexture() ; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 49e10c4790..6a3f186531 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -30,6 +30,7 @@ #include "llvertexbuffer.h" #include "llcubemap.h" +#include "llglslshader.h" #include "llimagegl.h" #include "llrendertarget.h" #include "lltexture.h" @@ -46,14 +47,15 @@ S32 gGLViewport[4]; U32 LLRender::sUICalls = 0; U32 LLRender::sUIVerts = 0; -static const U32 LL_NUM_TEXTURE_LAYERS = 16; +static const U32 LL_NUM_TEXTURE_LAYERS = 32; static const U32 LL_NUM_LIGHT_UNITS = 8; static GLenum sGLTextureType[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_CUBE_MAP_ARB + GL_TEXTURE_CUBE_MAP_ARB, + GL_TEXTURE_2D_MULTISAMPLE }; static GLint sGLAddressMode[] = @@ -119,14 +121,29 @@ void LLTexUnit::refreshState(void) gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); + + // + // Per apple spec, don't call glEnable/glDisable when index exceeds max texture units + // http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html + // + bool enableDisable = (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE; + if (mCurrTexType != TT_NONE) { - glEnable(sGLTextureType[mCurrTexType]); + if (enableDisable) + { + glEnable(sGLTextureType[mCurrTexType]); + } + glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); } else { - glDisable(GL_TEXTURE_2D); + if (enableDisable) + { + glDisable(GL_TEXTURE_2D); + } + glBindTexture(GL_TEXTURE_2D, 0); } @@ -167,7 +184,11 @@ void LLTexUnit::enable(eTextureType type) mCurrTexType = type; gGL.flush(); - glEnable(sGLTextureType[type]); + if (type != LLTexUnit::TT_MULTISAMPLE_TEXTURE && + mIndex < gGLManager.mNumTextureUnits) + { + glEnable(sGLTextureType[type]); + } } } @@ -180,7 +201,12 @@ void LLTexUnit::disable(void) activate(); unbind(mCurrTexType); gGL.flush(); - glDisable(sGLTextureType[mCurrTexType]); + if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE && + mIndex < gGLManager.mNumTextureUnits) + { + glDisable(sGLTextureType[mCurrTexType]); + } + mCurrTexType = TT_NONE; } } @@ -268,7 +294,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); texture->updateBindStats(texture->mTextureMemory); mHasMipMaps = texture->mHasMipMaps; - if (texture->mTexOptionsDirty) + if (mIndex == 0 && texture->mTexOptionsDirty) { texture->mTexOptionsDirty = false; setTextureAddressMode(texture->mAddressMode); @@ -378,6 +404,7 @@ void LLTexUnit::unbind(eTextureType type) activate(); mCurrTexture = 0; glBindTexture(sGLTextureType[type], 0); + stop_glerror(); } } @@ -399,7 +426,7 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option) { - if (mIndex < 0 || mCurrTexture == 0) return; + if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return; gGL.flush(); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7ba14f7b40..41e7b35341 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -57,6 +57,7 @@ public: TT_TEXTURE = 0, // Standard 2D Texture TT_RECT_TEXTURE, // Non power of 2 texture TT_CUBE_MAP, // 6-sided cube map texture + TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample TT_NONE // No texture type is currently enabled } eTextureType; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index cd2556d435..b6463309e1 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -44,6 +44,7 @@ void check_framebuffer_status() case GL_FRAMEBUFFER_COMPLETE: break; default: + llwarns << "check_framebuffer_status failed -- " << std::hex << status << llendl; ll_fail("check_framebuffer_status failed"); break; } @@ -62,8 +63,7 @@ LLRenderTarget::LLRenderTarget() : mUseDepth(false), mRenderDepth(false), mUsage(LLTexUnit::TT_TEXTURE), - mSamples(0), - mSampleBuffer(NULL) + mSamples(0) { } @@ -72,23 +72,32 @@ LLRenderTarget::~LLRenderTarget() release(); } - -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, S32 samples) { stop_glerror(); + + release(); + mResX = resx; mResY = resy; mStencil = stencil; mUsage = usage; mUseDepth = depth; + mSamples = samples; - release(); + mSamples = gGLManager.getNumFBOFSAASamples(mSamples); + + if (mSamples > 1 && gGLManager.mHasTextureMultisample) + { + mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE; + //no support for multisampled stencil targets yet + mStencil = false; + } + else + { + mSamples = 0; + } if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) { @@ -145,29 +154,51 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt) stop_glerror(); - LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - stop_glerror(); - if (offset == 0) +#ifdef GL_ARB_texture_multisample + if (mSamples > 1) { - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE); } else - { //don't filter data attachments - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - if (mUsage != LLTexUnit::TT_RECT_TEXTURE) +#else + llassert_always(mSamples <= 1); +#endif { - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR); + LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } - else - { - // ATI doesn't support mirrored repeat for rectangular textures. - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + + stop_glerror(); + + if (mSamples == 0) + { + if (offset == 0) + { //use bilinear filtering on single texture render targets that aren't multisampled + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + stop_glerror(); + } + else + { //don't filter data attachments + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + stop_glerror(); + } + + if (mUsage != LLTexUnit::TT_RECT_TEXTURE) + { + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR); + stop_glerror(); + } + else + { + // ATI doesn't support mirrored repeat for rectangular textures. + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + } } + if (mFBO) { + stop_glerror(); glBindFramebuffer(GL_FRAMEBUFFER, mFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, LLTexUnit::getInternalType(mUsage), tex, 0); @@ -180,6 +211,12 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt) mTex.push_back(tex); + if (gDebugGL) + { //bind and unbind to validate target + bindTarget(); + flush(); + } + } void LLRenderTarget::allocateDepth() @@ -196,9 +233,20 @@ void LLRenderTarget::allocateDepth() { LLImageGL::generateTextures(1, &mDepth); gGL.getTexUnit(0)->bindManual(mUsage, mDepth); - U32 internal_type = LLTexUnit::getInternalType(mUsage); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + if (mSamples == 0) + { + U32 internal_type = LLTexUnit::getInternalType(mUsage); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + } +#ifdef GL_ARB_texture_multisample + else + { + glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE); + } +#else + llassert_always(mSamples <= 1); +#endif } } @@ -238,6 +286,9 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); } + + check_framebuffer_status(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); target.mUseDepth = true; @@ -255,7 +306,7 @@ void LLRenderTarget::release() } else { - LLImageGL::deleteTextures(1, &mDepth); + LLImageGL::deleteTextures(1, &mDepth, true); stop_glerror(); } mDepth = 0; @@ -284,11 +335,12 @@ void LLRenderTarget::release() if (mTex.size() > 0) { - LLImageGL::deleteTextures(mTex.size(), &mTex[0]); + LLImageGL::deleteTextures(mTex.size(), &mTex[0], true); mTex.clear(); } + + mResX = mResY = 0; - mSampleBuffer = NULL; sBoundTarget = NULL; } @@ -297,34 +349,27 @@ void LLRenderTarget::bindTarget() if (mFBO) { stop_glerror(); - if (mSampleBuffer) - { - mSampleBuffer->bindTarget(this); - stop_glerror(); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + stop_glerror(); + if (gGLManager.mHasDrawBuffers) + { //setup multiple render targets + GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3}; + glDrawBuffersARB(mTex.size(), drawbuffers); } - else - { - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - stop_glerror(); - if (gGLManager.mHasDrawBuffers) - { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3}; - glDrawBuffersARB(mTex.size(), drawbuffers); - } - if (mTex.empty()) - { //no color buffer to draw to - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - } + if (mTex.empty()) + { //no color buffer to draw to + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } - check_framebuffer_status(); + check_framebuffer_status(); - stop_glerror(); - } + stop_glerror(); } glViewport(0, 0, mResX, mResY); @@ -406,50 +451,8 @@ void LLRenderTarget::flush(bool fetch_depth) else { stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - - if (mSampleBuffer) - { - LLGLEnable multisample(GL_MULTISAMPLE); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - stop_glerror(); - check_framebuffer_status(); - glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleBuffer->mFBO); - check_framebuffer_status(); - - stop_glerror(); - glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - stop_glerror(); - - if (mTex.size() > 1) - { - for (U32 i = 1; i < mTex.size(); ++i) - { - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - LLTexUnit::getInternalType(mUsage), mTex[i], 0); - stop_glerror(); - glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleBuffer->mTex[i]); - stop_glerror(); - glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST); - stop_glerror(); - } - - for (U32 i = 0; i < mTex.size(); ++i) - { - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, - LLTexUnit::getInternalType(mUsage), mTex[i], 0); - stop_glerror(); - glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_RENDERBUFFER, mSampleBuffer->mTex[i]); - stop_glerror(); - } - } - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); } } @@ -466,37 +469,36 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } - if (mSampleBuffer) + + if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) { - mSampleBuffer->copyContents(source, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + stop_glerror(); + + glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO); + check_framebuffer_status(); + gGL.getTexUnit(0)->bind(this, true); + stop_glerror(); + glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); + stop_glerror(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + stop_glerror(); } else { - if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) - { - stop_glerror(); - - glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO); - gGL.getTexUnit(0)->bind(this, true); - stop_glerror(); - glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - } - else - { - glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); - stop_glerror(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); - stop_glerror(); - check_framebuffer_status(); - stop_glerror(); - glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - } + glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); + stop_glerror(); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); + stop_glerror(); + check_framebuffer_status(); + stop_glerror(); + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + stop_glerror(); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + stop_glerror(); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + stop_glerror(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + stop_glerror(); } } @@ -539,179 +541,3 @@ void LLRenderTarget::getViewport(S32* viewport) viewport[3] = mResY; } -//================================================== -// LLMultisampleBuffer implementation -//================================================== -LLMultisampleBuffer::LLMultisampleBuffer() -{ - -} - -LLMultisampleBuffer::~LLMultisampleBuffer() -{ - release(); -} - -void LLMultisampleBuffer::release() -{ - if (mFBO) - { - glDeleteFramebuffers(1, (GLuint *) &mFBO); - mFBO = 0; - } - - if (mTex.size() > 0) - { - glDeleteRenderbuffers(mTex.size(), (GLuint *) &mTex[0]); - mTex.clear(); - } - - if (mDepth) - { - glDeleteRenderbuffers(1, (GLuint *) &mDepth); - mDepth = 0; - } -} - -void LLMultisampleBuffer::bindTarget() -{ - bindTarget(this); -} - -void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref) -{ - if (!ref) - { - ref = this; - } - - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - if (gGLManager.mHasDrawBuffers) - { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3}; - glDrawBuffersARB(ref->mTex.size(), drawbuffers); - } - - check_framebuffer_status(); - - glViewport(0, 0, mResX, mResY); - - sBoundTarget = this; -} - -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 ) -{ - stop_glerror(); - mResX = resx; - mResY = resy; - - mUsage = usage; - mUseDepth = depth; - mStencil = stencil; - - release(); - - mSamples = samples; - - if (mSamples <= 1) - { - llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl; - } - - stop_glerror(); - - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) - { - - if (depth) - { - stop_glerror(); - allocateDepth(); - stop_glerror(); - } - - glGenFramebuffers(1, (GLuint *) &mFBO); - - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - - if (mDepth) - { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); - if (mStencil) - { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); - } - } - - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - } - - addColorAttachment(color_fmt); -} - -void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) -{ - if (color_fmt == 0) - { - return; - } - - U32 offset = mTex.size(); - if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) - { - llerrs << "Too many color attachments!" << llendl; - } - - U32 tex; - glGenRenderbuffers(1, &tex); - - glBindRenderbuffer(GL_RENDERBUFFER, tex); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, color_fmt, mResX, mResY); - stop_glerror(); - - if (mFBO) - { - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex); - stop_glerror(); - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch (status) - { - case GL_FRAMEBUFFER_COMPLETE: - break; - default: - llerrs << "WTF? " << std::hex << status << llendl; - break; - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - mTex.push_back(tex); -} - -void LLMultisampleBuffer::allocateDepth() -{ - glGenRenderbuffers(1, (GLuint* ) &mDepth); - glBindRenderbuffer(GL_RENDERBUFFER, mDepth); - if (mStencil) - { - glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY); - } - else - { - glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT16, mResX, mResY); - } -} - diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 12dd1c8b90..094b58b562 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -71,10 +71,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); - - //provide this render target with a multisample resource. - void setSampleBuffer(LLMultisampleBuffer* buffer); + void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0); //add color buffer attachment //limit of 4 color attachments per render target @@ -141,7 +138,6 @@ public: static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; } protected: - friend class LLMultisampleBuffer; U32 mResX; U32 mResY; std::vector<U32> mTex; @@ -152,26 +148,8 @@ protected: bool mRenderDepth; LLTexUnit::eTextureType mUsage; U32 mSamples; - LLMultisampleBuffer* mSampleBuffer; - - static LLRenderTarget* sBoundTarget; -}; - -class LLMultisampleBuffer : public LLRenderTarget -{ -public: - LLMultisampleBuffer(); - virtual ~LLMultisampleBuffer(); - - 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 addColorAttachment(U32 color_fmt); - virtual void allocateDepth(); + static LLRenderTarget* sBoundTarget; }; #endif //!LL_MESA_HEADLESS diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 98a0a93084..bdc103b917 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -209,17 +209,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) if (features->hasWaterFog) { - if (!shader->attachObject("lighting/lightWaterF.glsl")) + if (features->disableTextureIndex) { - return FALSE; + if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightWaterF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } else { - if (!shader->attachObject("lighting/lightF.glsl")) + if (features->disableTextureIndex) { - return FALSE; + if (!shader->attachObject("lighting/lightNonIndexedF.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } } @@ -230,32 +252,76 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) if (features->isShiny && features->hasWaterFog) { - if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl")) + if (features->disableTextureIndex) { - return FALSE; + if (!shader->attachObject("lighting/lightFullbrightShinyWaterNonIndexedF.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } else if (features->hasWaterFog) { - if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) + if (features->disableTextureIndex) { - return FALSE; + if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } else if (features->isShiny) { - if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl")) + if (features->disableTextureIndex) { - return FALSE; + if (!shader->attachObject("lighting/lightFullbrightShinyNonIndexedF.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } else { - if (!shader->attachObject("lighting/lightFullbrightF.glsl")) + if (features->disableTextureIndex) { - return FALSE; + if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightFullbrightF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } } @@ -266,17 +332,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) if (features->hasWaterFog) { - if (!shader->attachObject("lighting/lightShinyWaterF.glsl")) + if (features->disableTextureIndex) { - return FALSE; + if (!shader->attachObject("lighting/lightShinyWaterNonIndexedF.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightShinyWaterF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } else { - if (!shader->attachObject("lighting/lightShinyF.glsl")) + if (features->disableTextureIndex) { - return FALSE; + if (!shader->attachObject("lighting/lightShinyNonIndexedF.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightShinyF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } } @@ -315,12 +403,12 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) } else { - LL_INFOS("ShaderLoading") << log << LL_ENDL; + LL_DEBUGS("ShaderLoading") << log << LL_ENDL; } } } -GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type) +GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels) { GLenum error = GL_NO_ERROR; if (gDebugGL) @@ -374,6 +462,106 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade GLcharARB* text[1024]; GLuint count = 0; + if (gGLManager.mGLVersion < 3.f) + { + //set version to 1.20 + text[count++] = strdup("#version 120\n"); + } + else + { //set version to 1.30 + text[count++] = strdup("#version 130\n"); + } + + //copy preprocessor definitions into buffer + for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter) + { + std::string define = "#define " + iter->first + " " + iter->second + "\n"; + text[count++] = (GLcharARB *) strdup(define.c_str()); + } + + if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB) + { + //use specified number of texture channels for indexed texture rendering + + /* prepend shader code that looks like this: + + uniform sampler2D tex0; + uniform sampler2D tex1; + uniform sampler2D tex2; + . + . + . + uniform sampler2D texN; + + varying float vary_texture_index; + + vec4 diffuseLookup(vec2 texcoord) + { + switch (int(vary_texture_index+0.25)) + { + case 0: return texture2D(tex0, texcoord); + case 1: return texture2D(tex1, texcoord); + case 2: return texture2D(tex2, texcoord); + . + . + . + case N: return texture2D(texN, texcoord); + } + + return vec4(0,0,0,0); + } + */ + + //uniform declartion + for (S32 i = 0; i < texture_index_channels; ++i) + { + std::string decl = llformat("uniform sampler2D tex%d;\n", i); + text[count++] = strdup(decl.c_str()); + } + + text[count++] = strdup("varying float vary_texture_index;\n"); + text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n"); + text[count++] = strdup("{\n"); + + + if (gGLManager.mGLVersion >= 3.f) + { + text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n"); + text[count++] = strdup("\t{\n"); + + //switch body + for (S32 i = 0; i < texture_index_channels; ++i) + { + std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i); + text[count++] = strdup(case_str.c_str()); + } + + text[count++] = strdup("\t}\n"); + } + else + { + //switches aren't supported, make block that looks like: + /* + int ti = int(vary_texture_index+0.25); + if (ti == 0) return texture2D(tex0, texcoord); + if (ti == 1) return texture2D(tex1, texcoord); + . + . + . + if (ti == N) return texture2D(texN, texcoord); + */ + + text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n"); + for (S32 i = 0; i < texture_index_channels; ++i) + { + std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i); + text[count++] = strdup(if_str.c_str()); + } + } + + text[count++] = strdup("\treturn vec4(0,0,0,0);\n"); + text[count++] = strdup("}\n"); + } //copy file into memory while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) ) @@ -457,7 +645,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (shader_level > 1) { shader_level--; - return loadShaderFile(filename,shader_level,type); + return loadShaderFile(filename,shader_level,type,texture_index_channels); } LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL; } diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index c54c4608d7..2f30103811 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -43,7 +43,7 @@ public: void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE); BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE); BOOL validateProgramObject(GLhandleARB obj); - GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type); + GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1); // Implemented in the application to actually point to the shader directory. virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual @@ -60,6 +60,9 @@ public: std::vector<std::string> mReservedUniforms; + //preprocessor definitions (name/value) + std::map<std::string, std::string> mDefinitions; + protected: // our parameter manager singleton instance diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 8c9171ccf4..4a0b964e61 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -934,8 +934,26 @@ void LLVertexBuffer::allocateClientIndexBuffer() } } +bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count) +{ + S32 end = index+count; + S32 region_end = region.mIndex+region.mCount; + + if (end < region.mIndex || + index > region_end) + { //gap exists, do not merge + return false; + } + + S32 new_end = llmax(end, region_end); + S32 new_index = llmin(index, region.mIndex); + region.mIndex = new_index; + region.mCount = new_end-new_index; + return true; +} + // Map for data access -U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access) +U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range) { LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); if (mFinal) @@ -947,8 +965,45 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access) llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl; } - if (!mVertexLocked && useVBOs()) + if (useVBOs()) { + + if (sDisableVBOMapping || gGLManager.mHasMapBufferRange) + { + if (count == -1) + { + count = mNumVerts-index; + } + + bool mapped = false; + //see if range is already mapped + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + { + MappedRegion& region = mMappedVertexRegions[i]; + if (region.mType == type) + { + if (expand_region(region, index, count)) + { + mapped = true; + break; + } + } + } + + if (!mapped) + { + //not already mapped, map new region + MappedRegion region(type, !sDisableVBOMapping && map_range ? -1 : index, count); + mMappedVertexRegions.push_back(region); + } + } + + if (mVertexLocked && map_range) + { + llerrs << "Attempted to map a specific range of a buffer that was already mapped." << llendl; + } + + if (!mVertexLocked) { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES); setBuffer(0, type); @@ -957,61 +1012,95 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access) if(sDisableVBOMapping) { + map_range = false; allocateClientVertexBuffer() ; } else { - U8* src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + U8* src = NULL; +#ifdef GL_ARB_map_buffer_range + if (gGLManager.mHasMapBufferRange) + { + if (map_range) + { + S32 offset = mOffsets[type] + sTypeSize[type]*index; + S32 length = (sTypeSize[type]*count+0xF) & ~0xF; + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT); + } + else + { + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); + } + } + else +#else + llassert_always(!gGLManager.mHasMapBufferRange); +#endif + { + map_range = false; + src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src); mAlignedOffset = mMappedData - src; stop_glerror(); } - } - - - if (!mMappedData) - { - log_glerror(); - - //check the availability of memory - U32 avail_phy_mem, avail_vir_mem; - LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ; - llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ; - llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl; - - if(!sDisableVBOMapping) - { - //-------------------- - //print out more debug info before crash - llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; - GLint size ; - glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; - llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; - //-------------------- + + if (!mMappedData) + { + log_glerror(); + + //check the availability of memory + U32 avail_phy_mem, avail_vir_mem; + LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ; + llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ; + llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl; + + if(!sDisableVBOMapping) + { + //-------------------- + //print out more debug info before crash + llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; + GLint size ; + glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; + llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; + //-------------------- + + GLint buff; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLBuffer) + { + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + } - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) + + llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; + } + else { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + llerrs << "memory allocation for vertex data failed." << llendl ; } - - - llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; - } - else - { - llerrs << "memory allocation for vertex data failed." << llendl ; } + sMappedCount++; } - sMappedCount++; + } + else + { + map_range = false; } - return mMappedData; + if (map_range && !sDisableVBOMapping) + { + return mMappedData; + } + else + { + return mMappedData+mOffsets[type]+sTypeSize[type]*index; + } } -U8* LLVertexBuffer::mapIndexBuffer(S32 access) +U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); if (mFinal) @@ -1023,8 +1112,41 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access) llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl; } - if (!mIndexLocked && useVBOs()) + if (useVBOs()) { + if (sDisableVBOMapping || gGLManager.mHasMapBufferRange) + { + if (count == -1) + { + count = mNumIndices-index; + } + + bool mapped = false; + //see if range is already mapped + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + { + MappedRegion& region = mMappedIndexRegions[i]; + if (expand_region(region, index, count)) + { + mapped = true; + break; + } + } + + if (!mapped) + { + //not already mapped, map new region + MappedRegion region(TYPE_INDEX, !sDisableVBOMapping && map_range ? -1 : index, count); + mMappedIndexRegions.push_back(region); + } + } + + if (mIndexLocked && map_range) + { + llerrs << "Attempted to map a specific range of a buffer that was already mapped." << llendl; + } + + if (!mIndexLocked) { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); @@ -1034,12 +1156,36 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access) if(sDisableVBOMapping) { + map_range = false; allocateClientIndexBuffer() ; } else { - U8* src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - mMappedIndexData = LL_NEXT_ALIGNED_ADDRESS<U8>(src); + U8* src = NULL; +#ifdef GL_ARB_map_buffer_range + if (gGLManager.mHasMapBufferRange) + { + if (map_range) + { + S32 offset = sizeof(U16)*index; + S32 length = sizeof(U16)*count; + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT); + } + else + { + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); + } + } + else +#else + llassert_always(!gGLManager.mHasMapBufferRange); +#endif + { + map_range = false; + src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + + mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src); mAlignedIndexOffset = mMappedIndexData - src; stop_glerror(); } @@ -1068,31 +1214,81 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 access) sMappedCount++; } + else + { + map_range = false; + } - return mMappedIndexData ; + if (map_range && !sDisableVBOMapping) + { + return mMappedIndexData; + } + else + { + return mMappedIndexData + sizeof(U16)*index; + } } void LLVertexBuffer::unmapBuffer(S32 type) { LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER); - if (!useVBOs()) + if (!useVBOs() || type == -2) { return ; //nothing to unmap } bool updated_all = false ; + if (mMappedData && mVertexLocked && type != TYPE_INDEX) { updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating if(sDisableVBOMapping) { - stop_glerror(); - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData); - stop_glerror(); + if (!mMappedVertexRegions.empty()) + { + stop_glerror(); + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + { + const MappedRegion& region = mMappedVertexRegions[i]; + S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; + S32 length = sTypeSize[region.mType]*region.mCount; + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, mMappedData+offset); + stop_glerror(); + } + + mMappedVertexRegions.clear(); + } + else + { + stop_glerror(); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData); + stop_glerror(); + } } else { +#ifdef GL_ARB_map_buffer_range + if (gGLManager.mHasMapBufferRange) + { + if (!mMappedVertexRegions.empty()) + { + stop_glerror(); + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + { + const MappedRegion& region = mMappedVertexRegions[i]; + S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; + S32 length = sTypeSize[region.mType]*region.mCount; + glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length); + stop_glerror(); + } + + mMappedVertexRegions.clear(); + } + } +#else + llassert_always(!gGLManager.mHasMapBufferRange); +#endif stop_glerror(); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); stop_glerror(); @@ -1103,17 +1299,53 @@ void LLVertexBuffer::unmapBuffer(S32 type) mVertexLocked = FALSE ; sMappedCount--; } - - if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) + + if (mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) { if(sDisableVBOMapping) { - stop_glerror(); - glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData); - stop_glerror(); + if (!mMappedIndexRegions.empty()) + { + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + { + const MappedRegion& region = mMappedIndexRegions[i]; + S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; + S32 length = sizeof(U16)*region.mCount; + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, mMappedIndexData+offset); + stop_glerror(); + } + + mMappedIndexRegions.clear(); + } + else + { + stop_glerror(); + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData); + stop_glerror(); + } } else { +#ifdef GL_ARB_map_buffer_range + if (gGLManager.mHasMapBufferRange) + { + if (!mMappedIndexRegions.empty()) + { + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + { + const MappedRegion& region = mMappedIndexRegions[i]; + S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; + S32 length = sizeof(U16)*region.mCount; + glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length); + stop_glerror(); + } + + mMappedIndexRegions.clear(); + } + } +#else + llassert_always(!gGLManager.mHasMapBufferRange); +#endif stop_glerror(); glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); stop_glerror(); @@ -1152,19 +1384,19 @@ template <class T,S32 type> struct VertexBufferStrider typedef LLStrider<T> strider_t; static bool get(LLVertexBuffer& vbo, strider_t& strider, - S32 index) + S32 index, S32 count, bool map_range) { if (type == LLVertexBuffer::TYPE_INDEX) { - S32 stride = sizeof(T); + U8* ptr = vbo.mapIndexBuffer(index, count, map_range); - if (vbo.mapIndexBuffer() == NULL) + if (ptr == NULL) { llwarns << "mapIndexBuffer failed!" << llendl; return FALSE; } - strider = (T*)(vbo.getMappedIndices() + index*stride); + strider = (T*)ptr; strider.setStride(0); return TRUE; } @@ -1172,13 +1404,15 @@ template <class T,S32 type> struct VertexBufferStrider { S32 stride = LLVertexBuffer::sTypeSize[type]; - if (vbo.mapVertexBuffer(type) == NULL) + U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range); + + if (ptr == NULL) { llwarns << "mapVertexBuffer failed!" << llendl; return FALSE; } - strider = (T*)(vbo.getMappedData() + vbo.getOffset(type)+index*stride); + strider = (T*)ptr; strider.setStride(stride); return TRUE; } @@ -1190,55 +1424,48 @@ template <class T,S32 type> struct VertexBufferStrider } }; -bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index) -{ - return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index); -} -bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index) +bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index); + return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index) +bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index); + return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index) +bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index); + return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index, count, map_range); } -/*bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index) +bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index); + return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getTexCoord3Strider(LLStrider<LLVector2>& strider, S32 index) -{ - return VertexBufferStrider<LLVector2,TYPE_TEXCOORD3>::get(*this, strider, index); -}*/ -bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index) + +bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index); + return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index) +bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index); + return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index) +bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index); + return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index) +bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index); + return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index) +bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index); + return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index) +bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index); + return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index, count, map_range); } //---------------------------------------------------------------------------- @@ -1497,17 +1724,16 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const } if (data_mask & MAP_VERTEX) { - glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + if (data_mask & MAP_TEXTURE_INDEX) + { + glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } + else + { + glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } } llglassertok(); } -void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count) -{ - // TODO: use GL_APPLE_flush_buffer_range here - /*if (useVBOs() && !mFilthy) - { - - }*/ -} diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index a9f22193f8..aa5df305a6 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -77,6 +77,18 @@ protected: class LLVertexBuffer : public LLRefCount { public: + class MappedRegion + { + public: + S32 mType; + S32 mIndex; + S32 mCount; + + MappedRegion(S32 type, S32 index, S32 count) + : mType(type), mIndex(index), mCount(count) + { } + }; + LLVertexBuffer(const LLVertexBuffer& rhs) { *this = rhs; @@ -130,6 +142,9 @@ public: TYPE_CLOTHWEIGHT, TYPE_MAX, TYPE_INDEX, + + //no actual additional data, but indicates position.w is texture index + TYPE_TEXTURE_INDEX, }; enum { MAP_VERTEX = (1<<TYPE_VERTEX), @@ -144,6 +159,7 @@ public: MAP_WEIGHT = (1<<TYPE_WEIGHT), MAP_WEIGHT4 = (1<<TYPE_WEIGHT4), MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), + MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX), }; protected: @@ -173,8 +189,8 @@ public: LLVertexBuffer(U32 typemask, S32 usage); // map for data access - U8* mapVertexBuffer(S32 type = -1, S32 access = -1); - U8* mapIndexBuffer(S32 access = -1); + U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range); + U8* mapIndexBuffer(S32 index, S32 count, bool map_range); // set for rendering virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0 @@ -189,16 +205,16 @@ public: // vb->getNormalStrider(norms); // setVertsNorms(verts, norms); // vb->unmapBuffer(); - bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0); - bool getIndexStrider(LLStrider<U16>& strider, S32 index=0); - bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0); - bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0); - bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0); - bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0); - bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0); - bool getWeightStrider(LLStrider<F32>& strider, S32 index=0); - bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0); - bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0); + bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false); BOOL isEmpty() const { return mEmpty; } BOOL isLocked() const { return mVertexLocked || mIndexLocked; } @@ -218,8 +234,6 @@ public: S32 getOffset(S32 type) const { return mOffsets[type]; } S32 getUsage() const { return mUsage; } - void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count); - void draw(U32 mode, U32 count, U32 indices_offset) const; void drawArrays(U32 mode, U32 offset, U32 count) const; void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; @@ -253,20 +267,8 @@ protected: BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded) S32 mOffsets[TYPE_MAX]; - class DirtyRegion - { - public: - U32 mIndex; - U32 mCount; - U32 mIndicesIndex; - U32 mIndicesCount; - - DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic) - : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic) - { } - }; - - std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild + std::vector<MappedRegion> mMappedVertexRegions; + std::vector<MappedRegion> mMappedIndexRegions; public: static S32 sCount; diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp index 39385786bc..820e7cb26a 100644 --- a/indra/llui/llresmgr.cpp +++ b/indra/llui/llresmgr.cpp @@ -337,7 +337,7 @@ LLLocale::LLLocale(const std::string& locale_string) char* new_locale_string = setlocale( LC_ALL, locale_string.c_str()); if ( new_locale_string == NULL) { - llwarns << "Failed to set locale " << locale_string << llendl; + LL_WARNS_ONCE("LLLocale") << "Failed to set locale " << locale_string << LL_ENDL; setlocale(LC_ALL, SYSTEM_LOCALE.c_str()); } //else diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 6b4e9cf923..15a7438ec9 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params() : label_width("label_width"), decimal_digits("decimal_digits"), allow_text_entry("allow_text_entry", true), + label_wrap("label_wrap", false), text_enabled_color("text_enabled_color"), text_disabled_color("text_disabled_color"), up_button("up_button"), @@ -80,6 +81,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) { LLRect label_rect( 0, centered_top, label_width, centered_bottom ); LLTextBox::Params params; + params.wrap(p.label_wrap); params.name("SpinCtrl Label"); params.rect(label_rect); params.initial_value(p.label()); diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index 8960971594..d197084e38 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -44,6 +44,7 @@ public: Optional<S32> label_width; Optional<U32> decimal_digits; Optional<bool> allow_text_entry; + Optional<bool> label_wrap; Optional<LLUIColor> text_enabled_color; Optional<LLUIColor> text_disabled_color; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 1cc3cc04d6..349dbc3405 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -280,7 +280,7 @@ bool LLTextBase::truncate() if (getLength() >= S32(mMaxTextByteLength / 4)) { // Have to check actual byte size - LLWString text(getWText()); + LLWString text(getWText()); S32 utf8_byte_size = wstring_utf8_length(text); if ( utf8_byte_size > mMaxTextByteLength ) { @@ -547,8 +547,7 @@ void LLTextBase::drawText() } LLRect text_rect(line.mRect); - text_rect.mRight = llmin(mDocumentView->getRect().getWidth(), text_rect.mRight); // clamp right edge to document extents - text_rect.translate(mVisibleTextRect.mLeft, mVisibleTextRect.mBottom); // translate into display region of text widget + text_rect.mRight = mDocumentView->getRect().getWidth(); // clamp right edge to document extents text_rect.translate(mDocumentView->getRect().mLeft, mDocumentView->getRect().mBottom); // adjust by scroll position // draw a single line of text @@ -655,7 +654,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s } text.insert(pos, wstr); - getViewModel()->setDisplay(text); + getViewModel()->setDisplay(text); if ( truncate() ) { @@ -670,7 +669,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length) { - LLWString text(getWText()); + LLWString text(getWText()); segment_set_t::iterator seg_iter = getSegIterContaining(pos); while(seg_iter != mSegments.end()) { @@ -717,7 +716,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length) } text.erase(pos, length); - getViewModel()->setDisplay(text); + getViewModel()->setDisplay(text); // recreate default segment in case we erased everything createDefaultSegment(); @@ -734,9 +733,9 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc) { return 0; } - LLWString text(getWText()); + LLWString text(getWText()); text[pos] = wc; - getViewModel()->setDisplay(text); + getViewModel()->setDisplay(text); onValueChange(pos, pos + 1); needsReflow(pos); @@ -857,7 +856,7 @@ BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask) // Did we just click on a link? if (mURLClickSignal && cur_segment->getStyle() - && cur_segment->getStyle()->isLink()) + && cur_segment->getStyle()->isLink()) { // *TODO: send URL here? (*mURLClickSignal)(this, LLSD() ); @@ -1035,27 +1034,27 @@ void LLTextBase::draw() gl_rect_2d(text_rect, bg_color % alpha, TRUE); } - bool should_clip = mClip || mScroller != NULL; - { LLLocalClipRect clip(text_rect, should_clip); + bool should_clip = mClip || mScroller != NULL; + { LLLocalClipRect clip(text_rect, should_clip); - // draw document view - if (mScroller) + // draw document view + if (mScroller) + { + drawChild(mScroller); + } + else { - drawChild(mScroller); - } - else - { - drawChild(mDocumentView); - } + drawChild(mDocumentView); + } drawSelectionBackground(); drawText(); drawCursor(); } - mDocumentView->setVisible(FALSE); - LLUICtrl::draw(); - mDocumentView->setVisible(TRUE); + mDocumentView->setVisible(FALSE); + LLUICtrl::draw(); + mDocumentView->setVisible(TRUE); } @@ -1119,8 +1118,7 @@ void LLTextBase::updateScrollFromCursor() // scroll so that the cursor is at the top of the page LLRect scroller_doc_window = getVisibleDocumentRect(); - LLRect cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos); - cursor_rect_doc.translate(scroller_doc_window.mLeft, scroller_doc_window.mBottom); + LLRect cursor_rect_doc = getDocRectFromDocIndex(mCursorPos); mScroller->scrollToShowRect(cursor_rect_doc, LLRect(0, scroller_doc_window.getHeight() - 5, scroller_doc_window.getWidth(), 5)); } @@ -1366,9 +1364,9 @@ S32 LLTextBase::getLineStart( S32 line ) const { S32 num_lines = getLineCount(); if (num_lines == 0) - { + { return 0; - } + } line = llclamp(line, 0, num_lines-1); return mLineInfoList[line].mDocIndexStart; @@ -1378,9 +1376,9 @@ S32 LLTextBase::getLineEnd( S32 line ) const { S32 num_lines = getLineCount(); if (num_lines == 0) - { + { return 0; - } + } line = llclamp(line, 0, num_lines-1); return mLineInfoList[line].mDocIndexEnd; @@ -1656,7 +1654,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para LLUrlMatch match; std::string text = new_text; while ( LLUrlRegistry::instance().findUrl(text, match, - boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) ) + boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) ) { LLTextUtil::processUrlMatch(&match,this); @@ -1949,7 +1947,7 @@ void LLTextBase::setWText(const LLWString& text) const LLWString& LLTextBase::getWText() const { - return getViewModel()->getDisplay(); + return getViewModel()->getDisplay(); } // If round is true, if the position is on the right half of a character, the cursor @@ -1960,9 +1958,12 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, { // Figure out which line we're nearest to. LLRect visible_region = getVisibleDocumentRect(); + LLRect doc_rect = mDocumentView->getRect(); + + S32 doc_y = local_y - doc_rect.mBottom; // binary search for line that starts before local_y - line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mVisibleTextRect.mBottom + visible_region.mBottom, compare_bottom()); + line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), doc_y, compare_bottom()); if (line_iter == mLineInfoList.end()) { @@ -1970,7 +1971,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, } S32 pos = getLength(); - S32 start_x = mVisibleTextRect.mLeft + line_iter->mRect.mLeft - visible_region.mLeft; + S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; segment_set_t::iterator line_seg_iter; S32 line_seg_offset; @@ -1992,7 +1993,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, } // if we've reached a line of text *below* the mouse cursor, doc index is first character on that line - if (hit_past_end_of_line && local_y - mVisibleTextRect.mBottom + visible_region.mBottom > line_iter->mRect.mTop) + if (hit_past_end_of_line && doc_y > line_iter->mRect.mTop) { pos = segment_line_start; break; @@ -2461,7 +2462,7 @@ LLRect LLTextBase::getVisibleDocumentRect() const LLRect doc_rect = mDocumentView->getLocalRect(); doc_rect.mLeft -= mDocumentView->getRect().mLeft; // adjust for height of text above widget baseline - doc_rect.mBottom = llmin(0, doc_rect.getHeight() - mVisibleTextRect.getHeight()); + doc_rect.mBottom = doc_rect.getHeight() - mVisibleTextRect.getHeight(); return doc_rect; } } @@ -2575,21 +2576,21 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele LLColor4 color = (mEditor.getReadOnly() ? mStyle->getReadOnlyColor() : mStyle->getColor()) % alpha; - if( selection_start > seg_start ) + if( selection_start > seg_start ) { // Draw normally S32 start = seg_start; S32 end = llmin( selection_start, seg_end ); S32 length = end - start; font->render(text, start, - rect, - color, - LLFontGL::LEFT, mEditor.mVAlign, - LLFontGL::NORMAL, - mStyle->getShadowType(), - length, - &right_x, - mEditor.getUseEllipses()); + rect, + color, + LLFontGL::LEFT, mEditor.mVAlign, + LLFontGL::NORMAL, + mStyle->getShadowType(), + length, + &right_x, + mEditor.getUseEllipses()); } rect.mLeft = (S32)ceil(right_x); @@ -2601,14 +2602,14 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele S32 length = end - start; font->render(text, start, - rect, - mStyle->getSelectedColor().get(), - LLFontGL::LEFT, mEditor.mVAlign, - LLFontGL::NORMAL, - LLFontGL::NO_SHADOW, - length, - &right_x, - mEditor.getUseEllipses()); + rect, + mStyle->getSelectedColor().get(), + LLFontGL::LEFT, mEditor.mVAlign, + LLFontGL::NORMAL, + LLFontGL::NO_SHADOW, + length, + &right_x, + mEditor.getUseEllipses()); } rect.mLeft = (S32)ceil(right_x); if( selection_end < seg_end ) @@ -2618,14 +2619,14 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele S32 end = seg_end; S32 length = end - start; font->render(text, start, - rect, - color, - LLFontGL::LEFT, mEditor.mVAlign, - LLFontGL::NORMAL, - mStyle->getShadowType(), - length, - &right_x, - mEditor.getUseEllipses()); + rect, + color, + LLFontGL::LEFT, mEditor.mVAlign, + LLFontGL::NORMAL, + mStyle->getShadowType(), + length, + &right_x, + mEditor.getUseEllipses()); } return right_x; } diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index b6d1ce61e5..2c581cf8d6 100644 --- a/indra/llvfs/CMakeLists.txt +++ b/indra/llvfs/CMakeLists.txt @@ -62,11 +62,15 @@ list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES}) add_library (llvfs ${llvfs_SOURCE_FILES}) -target_link_libraries(llvfs +set(vfs_BOOST_LIBRARIES ${BOOST_FILESYSTEM_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ) +target_link_libraries(llvfs + ${vfs_BOOST_LIBRARIES} + ) + if (DARWIN) include(CMakeFindFrameworks) find_library(CARBON_LIBRARY Carbon) @@ -76,15 +80,21 @@ endif (DARWIN) # Add tests if (LL_TESTS) - include(LLAddBuildTest) - # UNIT TESTS - SET(llvfs_TEST_SOURCE_FILES - # none so far - ) - LL_ADD_PROJECT_UNIT_TESTS(llvfs "${llvfs_TEST_SOURCE_FILES}") - - # INTEGRATION TESTS - set(test_libs llmath llcommon llvfs ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) - # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests. - LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}") + include(LLAddBuildTest) + # UNIT TESTS + SET(llvfs_TEST_SOURCE_FILES + lldiriterator.cpp + ) + + set_source_files_properties(lldiriterator.cpp + PROPERTIES + LL_TEST_ADDITIONAL_LIBRARIES "${vfs_BOOST_LIBRARIES}" + ) + LL_ADD_PROJECT_UNIT_TESTS(llvfs "${llvfs_TEST_SOURCE_FILES}") + + # INTEGRATION TESTS + set(test_libs llmath llcommon llvfs ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) + + # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests. + LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}") endif (LL_TESTS) diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp index 8f48f92e2a..489bc3e4a7 100644 --- a/indra/llvfs/lldir_mac.cpp +++ b/indra/llvfs/lldir_mac.cpp @@ -258,38 +258,6 @@ U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &ma return (file_count); } -S32 LLDir_Mac::deleteFilesInDir(const std::string &dirname, const std::string &mask) -{ - glob_t g; - S32 result = 0; - - std::string tmp_str; - tmp_str = dirname; - tmp_str += mask; - - if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0) - { - int i; - - for(i = 0; i < g.gl_pathc; i++) - { -// llinfos << "deleteFilesInDir: deleting number " << i << ", path is " << g.gl_pathv[i] << llendl; - - if(unlink(g.gl_pathv[i]) != 0) - { - result = errno; - - llwarns << "Problem removing " << g.gl_pathv[i] << " - errorcode: " - << result << llendl; - } - } - - globfree(&g); - } - - return(result); -} - std::string LLDir_Mac::getCurPath() { char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ diff --git a/indra/llvfs/lldir_mac.h b/indra/llvfs/lldir_mac.h index bc3f0fac00..d190d70be4 100644 --- a/indra/llvfs/lldir_mac.h +++ b/indra/llvfs/lldir_mac.h @@ -44,7 +44,6 @@ public: /*virtual*/ void initAppDirs(const std::string &app_name, const std::string& app_read_only_data_dir); - virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask); virtual std::string getCurPath(); virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask); virtual BOOL fileExists(const std::string &filename) const; diff --git a/indra/llvfs/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp index 041436ed92..25550321f0 100644 --- a/indra/llvfs/lldiriterator.cpp +++ b/indra/llvfs/lldiriterator.cpp @@ -121,6 +121,14 @@ bool LLDirIterator::Impl::next(std::string &fname) return found; } +/** +Converts the incoming glob into a regex. This involves +converting incoming glob expressions to regex equivilents and +at the same time, escaping any regex meaningful characters which +do not have glob meaning, i.e. + .()+|^$ +in the input. +*/ std::string glob_to_regex(const std::string& glob) { std::string regex; @@ -135,9 +143,6 @@ std::string glob_to_regex(const std::string& glob) switch (c) { - case '.': - regex+="\\."; - break; case '*': if (glob.begin() == i) { @@ -170,8 +175,16 @@ std::string glob_to_regex(const std::string& glob) case '!': regex+= square_brace_open ? '^' : c; break; + case '.': // This collection have different regex meaning + case '^': // and so need escaping. + case '(': + case ')': + case '+': + case '|': + case '$': + regex += '\\'; default: - regex+=c; + regex += c; break; } diff --git a/indra/llvfs/tests/lldiriterator_test.cpp b/indra/llvfs/tests/lldiriterator_test.cpp new file mode 100644 index 0000000000..505d86faa7 --- /dev/null +++ b/indra/llvfs/tests/lldiriterator_test.cpp @@ -0,0 +1,65 @@ +/** + * @file lldiriterator_test.cpp + * @date 2011-06 + * @brief LLDirIterator test cases. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only., + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "lltut.h" +#include "../lldiriterator.h" + + +namespace tut +{ + + struct LLDirIteratorFixture + { + LLDirIteratorFixture() + { + } + }; + typedef test_group<LLDirIteratorFixture> LLDirIteratorTest_factory; + typedef LLDirIteratorTest_factory::object LLDirIteratorTest_t; + LLDirIteratorTest_factory tf("LLDirIterator"); + + /* + CHOP-662 was originally introduced to deal with crashes deleting files from + a directory (VWR-25500). However, this introduced a crash looking for + old chat logs as the glob_to_regex function in lldiriterator wasn't escaping lots of regexp characters + */ + void test_chop_662(void) + { + // Check a selection of bad group names from the crash reports + LLDirIterator iter(".","+bad-group-name]+??-??.*"); + LLDirIterator iter1(".","))--@---bad-group-name2((??-??.*\\.txt"); + LLDirIterator iter2(".","__^v--x)Cuide d sua vida(x--v^__??-??.*"); + } + + template<> template<> + void LLDirIteratorTest_t::test<1>() + { + test_chop_662(); + } + +} diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp index 4dfaaed4e1..c87617c9ff 100644 --- a/indra/llwindow/llkeyboardheadless.cpp +++ b/indra/llwindow/llkeyboardheadless.cpp @@ -46,5 +46,28 @@ MASK LLKeyboardHeadless::currentMask(BOOL for_mouse_event) { return MASK_NONE; } void LLKeyboardHeadless::scanKeyboard() -{ } +{ + for (S32 key = 0; key < KEY_COUNT; key++) + { + // Generate callback if any event has occurred on this key this frame. + // Can't just test mKeyLevel, because this could be a slow frame and + // key might have gone down then up. JC + if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) + { + mCurScanKey = key; + mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); + } + } + + // Reset edges for next frame + for (S32 key = 0; key < KEY_COUNT; key++) + { + mKeyUp[key] = FALSE; + mKeyDown[key] = FALSE; + if (mKeyLevel[key]) + { + mKeyLevelFrameCount[key]++; + } + } +} diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp index 967c69fea9..7ffe53a307 100644 --- a/indra/lscript/lscript_library/lscript_library.cpp +++ b/indra/lscript/lscript_library/lscript_library.cpp @@ -461,6 +461,9 @@ void LLScriptLibrary::init() addFunction(10.f, 0.f, dummy_func, "llGetDisplayName", "s", "k"); addFunction(10.f, 0.f, dummy_func, "llRequestDisplayName", "k", "k"); + addFunction(10.f, 0.f, dummy_func, "llGetEnv", "s", "s"); + addFunction(10.f, 0.f, dummy_func, "llRegionSayTo", NULL, "kis"); + // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only // IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST. diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index 9ba8edbb59..27f3c7260e 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -1168,6 +1168,66 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) authResponse(message_in); } else + if(message_name == "js_expose_object") + { +#if LLQTWEBKIT_API_VERSION >= 9 + bool expose_object = message_in.getValueBoolean( "expose" ); + LLQtWebKit::getInstance()->setExposeObject( expose_object ); +#endif + } + else + if(message_name == "js_values_valid") + { +#if LLQTWEBKIT_API_VERSION >= 9 + bool valid = message_in.getValueBoolean( "valid" ); + LLQtWebKit::getInstance()->setValuesValid( valid ); +#endif + } + else + if(message_name == "js_agent_location") + { +#if LLQTWEBKIT_API_VERSION >= 9 + F32 x = message_in.getValueReal("x"); + F32 y = message_in.getValueReal("y"); + F32 z = message_in.getValueReal("z"); + LLQtWebKit::getInstance()->setAgentLocation( x, y, z ); +#endif + } + else + if(message_name == "js_agent_global_location") + { +#if LLQTWEBKIT_API_VERSION >= 9 + F32 x = message_in.getValueReal("x"); + F32 y = message_in.getValueReal("y"); + F32 z = message_in.getValueReal("z"); + LLQtWebKit::getInstance()->setAgentGlobalLocation( x, y, z ); +#endif + } + else + if(message_name == "js_agent_orientation") + { +#if LLQTWEBKIT_API_VERSION >= 9 + F32 angle = message_in.getValueReal("angle"); + LLQtWebKit::getInstance()->setAgentOrientation( angle ); +#endif + } + else + if(message_name == "js_agent_region") + { +#if LLQTWEBKIT_API_VERSION >= 9 + const std::string& region = message_in.getValue("region"); + LLQtWebKit::getInstance()->setAgentRegion( region ); +#endif + } + else + if(message_name == "js_agent_maturity") + { +#if LLQTWEBKIT_API_VERSION >= 9 + const std::string& maturity = message_in.getValue("maturity"); + LLQtWebKit::getInstance()->setAgentMaturity( maturity ); +#endif + } + else { // std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl; } @@ -1324,4 +1384,3 @@ int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void return 0; } - diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index cbf22b75e8..523ea8a394 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -77,6 +77,7 @@ include_directories( set(viewer_SOURCE_FILES groupchatlistener.cpp + llaccountingquotamanager.cpp llagent.cpp llagentaccess.cpp llagentcamera.cpp @@ -243,6 +244,7 @@ set(viewer_SOURCE_FILES llfolderviewitem.cpp llfollowcam.cpp llfriendcard.cpp + llgesturelistener.cpp llgesturemgr.cpp llgiveinventory.cpp llglsandbox.cpp @@ -320,6 +322,7 @@ set(viewer_SOURCE_FILES llnearbychat.cpp llnearbychatbar.cpp llnearbychathandler.cpp + llnearbychatbarlistener.cpp llnetmap.cpp llnotificationalerthandler.cpp llnotificationgrouphandler.cpp @@ -626,6 +629,7 @@ set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake groupchatlistener.h + llaccountingquotamanager.h llagent.h llagentaccess.h llagentcamera.h @@ -795,6 +799,7 @@ set(viewer_HEADER_FILES llfolderviewitem.h llfollowcam.h llfriendcard.h + llgesturelistener.h llgesturemgr.h llgiveinventory.h llgroupactions.h @@ -871,6 +876,7 @@ set(viewer_HEADER_FILES llnearbychat.h llnearbychatbar.h llnearbychathandler.h + llnearbychatbarlistener.h llnetmap.h llnotificationhandler.h llnotificationmanager.h diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 937c4e4c6a..9f4e89691f 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -20,6 +20,7 @@ <key>tags</key> <array> <string>AppInit</string> + <string>Capabilities</string> <string>SystemInfo</string> <string>TextureCache</string> <string>AppCache</string> @@ -43,6 +44,7 @@ <array> <!-- sample entry for debugging a specific item --> <!-- <string>Voice</string> --> + <string>Capabilities</string> </array> </map> </array> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 78db307d64..76fecdf05e 100644..100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -708,6 +708,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>BrowserEnableJSObject</key> + <map> + <key>Comment</key> + <string>(WARNING: Advanced feature. Use if you are aware of the implications). Enable or disable the viewer to Javascript bridge object.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>BlockAvatarAppearanceMessages</key> <map> <key>Comment</key> @@ -3047,6 +3058,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>EnableGestureSounds</key> + <map> + <key>Comment</key> + <string>Play sounds from gestures</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>EnableMouselook</key> <map> <key>Comment</key> @@ -3245,17 +3267,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>FirstLoginThisInstall</key> - <map> - <key>Comment</key> - <string>Specifies that you have not successfully logged in since you installed the latest update</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>FirstName</key> <map> <key>Comment</key> @@ -3980,7 +3991,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> + <string>http://search-beta.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> </map> <key>WebProfileURL</key> <map> @@ -5578,10 +5589,10 @@ <key>Value</key> <real>0</real> </map> - <key>MeshUseWholeModelUpload</key> + <key>MeshUploadLogXML</key> <map> <key>Comment</key> - <string>Upload model in its entirety instead of mesh-by-mesh (new caps)</string> + <string>Verbose XML logging on mesh upload</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -5589,6 +5600,17 @@ <key>Value</key> <real>0</real> </map> + <key>MeshUploadFakeErrors</key> + <map> + <key>Comment</key> + <string>Force upload errors (for testing)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <real>0</real> + </map> <key>MigrateCacheDirectory</key> <map> <key>Comment</key> @@ -7091,7 +7113,76 @@ <key>Value</key> <integer>1</integer> </map> - <key>RenderAnisotropic</key> + + <key>OctreeMaxNodeCapacity</key> + <map> + <key>Comment</key> + <string>Maximum number of elements to store in a single octree node</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>128</integer> + </map> + + <key>OctreeStaticObjectSizeFactor</key> + <map> + <key>Comment</key> + <string>Multiplier on static object size for determining octree node size </string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>4</integer> + </map> + + <key>OctreeAlphaDistanceFactor</key> + <map> + <key>Comment</key> + <string>Multiplier on alpha object distance for determining octree node size </string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.1</real> + <real>0.0</real> + <real>0.0</real> + </array> + </map> + + <key>OctreeAttachmentSizeFactor</key> + <map> + <key>Comment</key> + <string>Multiplier on attachment size for determining octree node size </string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>4</integer> + </map> + + <key>OctreeDistanceFactor</key> + <map> + <key>Comment</key> + <string>Multiplier on distance for determining octree node size </string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.01</real> + <real>0.0</real> + <real>0.0</real> + </array> + </map> + + <key>RenderAnisotropic</key> <map> <key>Comment</key> <string>Render textures using anisotropic filtering</string> @@ -7188,7 +7279,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <integer>1.0</integer> + <real>1.0</real> </map> <key>RenderAvatarVP</key> <map> @@ -7444,6 +7535,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderMaxTextureIndex</key> + <map> + <key>Comment</key> + <string>Maximum texture index to use for indexed texture rendering.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>6</integer> + </map> <key>RenderDebugTextureBind</key> <map> <key>Comment</key> @@ -8589,7 +8691,7 @@ <key>Type</key> <string>S32</string> <key>Value</key> - <integer>8192</integer> + <integer>65536</integer> </map> <key>RenderMaxVBOSize</key> <map> @@ -8867,17 +8969,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderUseTriStrips</key> - <map> - <key>Comment</key> - <string>Use triangle strips for rendering prims.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>RenderUseFarClip</key> <map> <key>Comment</key> @@ -8942,7 +9033,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>RenderUseStreamVBO</key> <map> @@ -9052,7 +9143,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>3.0</real> + <real>2.0</real> </map> <key>MeshThreadCount</key> <map> @@ -9648,6 +9739,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>NearbyListShowMap</key> + <map> + <key>Comment</key> + <string>Show/hide map above nearby people list</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>NearbyListShowIcons</key> <map> <key>Comment</key> @@ -12395,7 +12497,7 @@ <key>Type</key> <string>S32</string> <key>Value</key> - <integer>-1</integer> + <integer>20</integer> </map> <key>WaterEditPresets</key> <map> @@ -12743,6 +12845,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>SLURLPassToOtherInstance</key> + <map> + <key>Comment</key> + <string>Pass execution to prevoius viewer instances if there is a given slurl</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>soundsbeacon</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl index 3f6b8b3323..b0fa0ddd3e 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 1ad87badfe..d9f29ced4f 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 a15846f192..2796222c68 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 05fe100372..d86ef19a04 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 4b8a7604a1..2eb814bd91 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index ef823c28b1..7613e50dca 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + attribute vec4 object_weight; diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl index 27ac59a840..2638351e96 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 f1aa549a47..86b189b282 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 3b12a07a27..4a0815a163 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -5,13 +5,14 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable -uniform sampler2D diffuseMap; uniform sampler2DRect depthMap; +vec4 diffuseLookup(vec2 texcoord); + uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -47,7 +48,7 @@ void main() vec4 pos = vec4(vary_position, 1.0); - vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 diff= diffuseLookup(gl_TexCoord[0].xy); vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a); vec4 color = diff * col; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl new file mode 100644 index 0000000000..b0d029dbf4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl @@ -0,0 +1,67 @@ +/** + * @file alphaF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2D diffuseMap; + + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_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 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; + + vec4 pos = vec4(vary_position, 1.0); + + vec4 diff= texture2D(diffuseMap,gl_TexCoord[0].xy); + + 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); + + color.rgb += diff.rgb * vary_pointlight_col.rgb; + + 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/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl index 5addbbb176..ac3f7189c2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getObjectSkinnedTransform(); @@ -35,19 +35,24 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa //get distance float d = length(lv); - //normalize light vector - lv *= 1.0/d; + float da = 0.0; + + if (d > 0.0 && la > 0.0 && fa > 0.0) + { + //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); + //distance attenuation + float dist2 = d*d/(la*la); + 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 + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 - //angular attenuation - da *= calcDirectionalLight(n, lv); + //angular attenuation + da *= calcDirectionalLight(n, lv); + } return da; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 525b68c437..44cb78e914 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); @@ -23,6 +23,7 @@ varying vec3 vary_fragcoord; varying vec3 vary_position; varying vec3 vary_light; varying vec3 vary_pointlight_col; +varying float vary_texture_index; uniform float near_clip; uniform float shadow_offset; @@ -36,19 +37,24 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa //get distance float d = length(lv); - //normalize light vector - lv *= 1.0/d; + float da = 0.0; + + if (d > 0.0 && la > 0.0 && fa > 0.0) + { + //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); + //distance attenuation + float dist2 = d*d/(la*la); + 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 + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 - //angular attenuation - da *= calcDirectionalLight(n, lv); + //angular attenuation + da *= calcDirectionalLight(n, lv); + } return da; } @@ -56,11 +62,13 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa void main() { //transform vertex - gl_Position = ftransform(); + vec4 vert = vec4(gl_Vertex.xyz, 1.0); + vary_texture_index = gl_Vertex.w; + gl_Position = gl_ModelViewProjectionMatrix * vert; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vec4 pos = (gl_ModelViewMatrix * vert); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); @@ -97,7 +105,7 @@ void main() gl_FogFragCoord = pos.z; - pos = gl_ModelViewProjectionMatrix * gl_Vertex; + pos = gl_ModelViewProjectionMatrix * vert; vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl index 164322c3a7..870d593311 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl index 5ae41cb730..c7a4f86727 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + mat4 getObjectSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index a2a7dea20d..68e4055cf2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); @@ -35,19 +35,24 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa //get distance float d = length(lv); - //normalize light vector - lv *= 1.0/d; + float da = 0.0; + + if (d > 0.0 && la > 0.0 && fa > 0.0) + { + //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); + //distance attenuation + float dist2 = d*d/(la*la); + 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 + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 - //angular attenuation - da *= calcDirectionalLight(n, lv); + //angular attenuation + da *= calcDirectionalLight(n, lv); + } return da; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl new file mode 100644 index 0000000000..7bc78fe407 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl @@ -0,0 +1,21 @@ +/** + * @file avatarEyesV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +varying vec3 vary_normal; + +void main() +{ + //transform vertex + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vary_normal = normalize(gl_NormalMatrix * gl_Normal); + + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 9748727147..3268618093 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 1b7ae06888..78986ab12e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -5,14 +5,17 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; +varying vec4 post_pos; void main() { //gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a); gl_FragColor = vec4(1,1,1,1); + + 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/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index cf6579a40d..f177fcd8f1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -5,12 +5,14 @@ * $/LicenseInfo$ */ -#version 120 + mat4 getSkinnedTransform(); attribute vec4 weight; +varying vec4 post_pos; + void main() { gl_TexCoord[0] = gl_MultiTexCoord0; @@ -30,8 +32,9 @@ void main() norm = normalize(norm); pos = gl_ProjectionMatrix * pos; - pos.z = max(pos.z, -pos.w+0.01); - gl_Position = pos; + post_pos = pos; + + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); 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 69c93799b5..7eac11287a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index d9f021b114..8c75c8045a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -26,7 +26,7 @@ uniform vec2 screen_res; vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = pos_screen.xy*2.0; sc /= screen_res; sc -= vec2(1.0,1.0); @@ -39,7 +39,7 @@ vec4 getPosition(vec2 pos_screen) void main() { - vec2 tc = vary_fragcoord.xy; + vec2 tc = vary_fragcoord.xy; vec3 norm = texture2DRect(normalMap, tc).xyz; norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm vec3 pos = getPosition(tc).xyz; diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl new file mode 100644 index 0000000000..6ca51377c1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl @@ -0,0 +1,113 @@ +/** + * @file blurLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS depthMap; +uniform sampler2DMS 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; + +vec3 texture2DMS3(sampler2DMS tex, ivec2 tc) +{ + vec3 ret = vec3(0,0,0); + for (int i = 0; i < samples; i++) + { + ret += texelFetch(tex, tc, i).rgb; + } + + return ret/samples; +} + +float texture2DMS1(sampler2DMS tex, ivec2 tc) +{ + float ret = 0; + for (int i = 0; i < samples; i++) + { + ret += texelFetch(tex, tc, i).r; + } + + return ret/samples; +} + +vec4 getPosition(ivec2 pos_screen) +{ + float depth = texture2DMS1(depthMap, pos_screen.xy); + 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 tc = vary_fragcoord.xy; + ivec2 itc = ivec2(tc); + + vec3 norm = texture2DMS3(normalMap, itc).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 pos = getPosition(itc).xyz; + vec4 ccol = texture2DRect(lightMap, tc).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; + + // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances + float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005; + + // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large + tc += ( (mod(tc.x+tc.y,2) - 0.5) * kern[1].z * dlt * 0.5 ); + + for (int i = 1; i < 4; i++) + { + vec2 samptc = tc + kern[i].z*dlt; + vec3 samppos = getPosition(ivec2(samptc)).xyz; + float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane + if (d*d <= pointplanedist_tolerance_pow2) + { + col += texture2DRect(lightMap, samptc)*kern[i].xyxx; + defined_weight += kern[i].xy; + } + } + for (int i = 1; i < 4; i++) + { + vec2 samptc = vec2(tc - kern[i].z*dlt); + vec3 samppos = getPosition(ivec2(samptc)).xyz; + float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane + if (d*d <= pointplanedist_tolerance_pow2) + { + col += texture2DRect(lightMap, samptc)*kern[i].xyxx; + defined_weight += kern[i].xy; + } + } + + col /= defined_weight.xyxx; + col.y *= col.y; + + 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 c2d05c601a..862f809de5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 37bfaac32c..75b4dc624a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; uniform sampler2D bumpMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl index d884f2e4a5..dc69519a85 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + varying vec3 vary_mat0; varying vec3 vary_mat1; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 9b109b2db6..5b6726488b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec3 vary_mat0; varying vec3 vary_mat1; diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl new file mode 100644 index 0000000000..ef300d5631 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -0,0 +1,79 @@ +/** + * @file WLCloudsF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +///////////////////////////////////////////////////////////////////////// +// The fragment shader for the sky +///////////////////////////////////////////////////////////////////////// + +varying vec4 vary_CloudColorSun; +varying vec4 vary_CloudColorAmbient; +varying float vary_CloudDensity; + +uniform sampler2D cloud_noise_texture; +uniform vec4 cloud_pos_density1; +uniform vec4 cloud_pos_density2; +uniform vec4 gamma; + +/// Soft clips the light with a gamma correction +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() +{ + // Set variables + vec2 uv1 = gl_TexCoord[0].xy; + vec2 uv2 = gl_TexCoord[1].xy; + + vec4 cloudColorSun = vary_CloudColorSun; + vec4 cloudColorAmbient = vary_CloudColorAmbient; + float cloudDensity = vary_CloudDensity; + vec2 uv3 = gl_TexCoord[2].xy; + vec2 uv4 = gl_TexCoord[3].xy; + + // Offset texture coords + uv1 += cloud_pos_density1.xy; //large texture, visible density + uv2 += cloud_pos_density1.xy; //large texture, self shadow + uv3 += cloud_pos_density2.xy; //small texture, visible density + uv4 += cloud_pos_density2.xy; //small texture, self shadow + + + // Compute alpha1, the main cloud opacity + float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z; + alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.); + + // And smooth + alpha1 = 1. - alpha1 * alpha1; + alpha1 = 1. - alpha1 * alpha1; + + + // Compute alpha2, for self shadowing effect + // (1 - alpha2) will later be used as percentage of incoming sunlight + float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5); + alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.); + + // And smooth + alpha2 = 1. - alpha2; + alpha2 = 1. - alpha2 * alpha2; + + // Combine + vec4 color; + color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient); + color *= 2.; + + /// Gamma correct for WL (soft clip effect). + gl_FragData[0] = vec4(scaleSoftClip(color.rgb), alpha1); + gl_FragData[1] = vec4(0.0,0.0,0.0,0.0); + gl_FragData[2] = vec4(0,0,1,0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl new file mode 100644 index 0000000000..3eac63076c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl @@ -0,0 +1,165 @@ +/** + * @file WLCloudsV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +////////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +// Output parameters +varying vec4 vary_CloudColorSun; +varying vec4 vary_CloudColorAmbient; +varying float vary_CloudDensity; + +// Inputs +uniform vec3 camPosLocal; + +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 max_y; + +uniform vec4 glow; + +uniform vec4 cloud_color; + +uniform vec4 cloud_scale; + +void main() +{ + + // World / view / projection + gl_Position = ftransform(); + + gl_TexCoord[0] = gl_MultiTexCoord0; + + // Get relative position + vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0); + + // Set altitude + if (P.y > 0.) + { + P *= (max_y.x / P.y); + } + else + { + P *= (-32000. / P.y); + } + + // Can normalize then + vec3 Pn = normalize(P); + float Plen = length(P); + + // Initialize temp variables + vec4 temp1 = vec4(0.); + vec4 temp2 = vec4(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 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + + // Calculate relative weights + temp1 = blue_density + haze_density.x; + blue_weight = blue_density / temp1; + haze_weight = haze_density.x / temp1; + + // Compute sunlight from P & lightnorm (for long rays like sky) + temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // Distance + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z); + + + // Compute haze glow + temp2.x = dot(Pn, lightnorm.xyz); + temp2.x = 1. - temp2.x; + // temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .001); + // 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; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5; + + // Dim sunlight by cloud shadow percentage + sunlight *= (1. - cloud_shadow.x); + + // Haze color below cloud + vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) + ); + + // CLOUDS + + sunlight = sunlight_color; + temp2.y = max(0., lightnorm.y * 2.); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // Cloud color out + vary_CloudColorSun = (sunlight * temp2.x) * cloud_color; + vary_CloudColorAmbient = tmpAmbient * cloud_color; + + // Attenuate cloud color by atmosphere + temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds + vary_CloudColorSun *= temp1; + vary_CloudColorAmbient *= temp1; + vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1); + + // Make a nice cloud density based on the cloud_shadow value that was passed in. + vary_CloudDensity = 2. * (cloud_shadow.x - 0.25); + + + // Texture coords + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[0].xy -= 0.5; + gl_TexCoord[0].xy /= cloud_scale.x; + gl_TexCoord[0].xy += 0.5; + + gl_TexCoord[1] = gl_TexCoord[0]; + gl_TexCoord[1].x += lightnorm.x * 0.0125; + gl_TexCoord[1].y += lightnorm.z * 0.0125; + + gl_TexCoord[2] = gl_TexCoord[0] * 16.; + gl_TexCoord[3] = gl_TexCoord[1] * 16.; + + // Combine these to minimize register use + vary_CloudColorAmbient += oHazeColorBelowCloud; + + // needs this to compile on mac + //vary_AtmosAttenuation = vec3(0.0,0.0,0.0); + + // END CLOUDS +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 35cfb80c93..43af480c50 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; @@ -20,3 +20,4 @@ void main() 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/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl new file mode 100644 index 0000000000..e7b5dcce7f --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -0,0 +1,19 @@ +/** + * @file diffuseIndexedF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +varying vec3 vary_normal; + +void main() +{ + vec3 col = gl_Color.rgb * diffuseLookup(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/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl index 9a45c03237..2c4caea109 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 03d3322cb6..b56d1493c3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -5,16 +5,18 @@ * $/LicenseInfo$ */ -#version 120 + varying vec3 vary_normal; +varying float vary_texture_index; void main() { //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + vary_texture_index = gl_Vertex.w; 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 3429877397..d781e08548 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -5,60 +5,24 @@ * $/LicenseInfo$ */ -#version 120 -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2D diffuseMap; -uniform sampler2DRect depthMap; -uniform sampler2D noiseMap; -uniform vec4 shadow_clip; -uniform vec2 screen_res; +#extension GL_ARB_texture_rectangle : enable vec3 fullbrightAtmosTransport(vec3 light); vec3 fullbrightScaleSoftClip(vec3 light); -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec4 vary_position; -varying vec3 vary_normal; -varying vec3 vary_fragcoord; - -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 = getPosition(frag).xyz; - float shadow = 1.0; - vec4 pos = vary_position; - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy)*gl_Color; + vec4 color = diffuseLookup(gl_TexCoord[0].xy)*gl_Color; color.rgb = fullbrightAtmosTransport(color.rgb); color.rgb = fullbrightScaleSoftClip(color.rgb); - //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 6c38d220e2..2eed044b7c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + void calcAtmospherics(vec3 inPositionEye); @@ -14,30 +14,23 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 scaleDownLight(vec3 light); vec3 scaleUpLight(vec3 light); -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec3 vary_normal; -varying vec3 vary_fragcoord; -uniform float near_clip; -varying vec4 vary_position; +varying float vary_texture_index; void main() { //transform vertex - gl_Position = ftransform(); + vec4 vert = vec4(gl_Vertex.xyz, 1.0); + vary_texture_index = gl_Vertex.w; + + gl_Position = gl_ModelViewProjectionMatrix*vert; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vec4 pos = (gl_ModelViewMatrix * gl_Vertex); - vary_position = pos; - + vec4 pos = (gl_ModelViewMatrix * vert); + calcAtmospherics(pos.xyz); gl_FrontColor = gl_Color; 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/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl index 75b555e8ae..41c149e774 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl index 8dc1410ea5..e86f2896da 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index e3c15a2ab2..fa811f0d55 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; uniform sampler2D normalMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl index 37148b3f1a..723777bd3a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl index 78df54d5dc..25e93ae266 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2DRect diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl index 0c820bfc6c..4baf1fc65a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index c5ddf31ac0..3c5c780d94 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -23,8 +23,9 @@ uniform float sun_wash; uniform int light_count; -uniform vec4 light[16]; -uniform vec4 light_col[16]; +#define MAX_LIGHT_COUNT 16 +uniform vec4 light[MAX_LIGHT_COUNT]; +uniform vec4 light_col[MAX_LIGHT_COUNT]; varying vec4 vary_fragcoord; uniform vec2 screen_res; @@ -35,7 +36,7 @@ uniform mat4 inv_proj; vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = pos_screen.xy*2.0; sc /= screen_res; sc -= vec2(1.0,1.0); @@ -63,50 +64,56 @@ void main() 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) + + // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop + for (int i = 0; i < MAX_LIGHT_COUNT; ++i) { + bool light_contrib = (i < light_count); + vec3 lv = light[i].xyz-pos; float dist2 = dot(lv,lv); dist2 /= light[i].w; if (dist2 > 1.0) { - continue; + light_contrib = false; } float da = dot(norm, lv); if (da < 0.0) { - continue; + light_contrib = false; } - - lv = normalize(lv); - da = dot(norm, lv); - - float fa = light_col[i].a+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) + if (light_contrib) { - //vec3 ref = dot(pos+lv, norm); + lv = normalize(lv); + da = dot(norm, lv); + + float fa = light_col[i].a+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; - float sa = dot(normalize(lv+npos),norm); + vec3 col = light_col[i].rgb*lit*diff; + //vec3 col = vec3(dist2, light_col[i].a, lit); - if (sa > 0.0) + if (spec.a > 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; + //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; } - - out_col += col; } if (dot(out_col, out_col) <= 0.0) diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl new file mode 100644 index 0000000000..6c43679acf --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl @@ -0,0 +1,137 @@ +/** + * @file multiPointLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS depthMap; +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS normalMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + + +uniform vec3 env_mat[3]; +uniform float sun_wash; + +uniform int light_count; + +#define MAX_LIGHT_COUNT 16 +uniform vec4 light[MAX_LIGHT_COUNT]; +uniform vec4 light_col[MAX_LIGHT_COUNT]; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform float far_z; + +uniform mat4 inv_proj; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen, sample).r; + vec2 sc = vec2(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; + ivec2 itc = ivec2(frag); + + int wght = 0; + vec3 fcol = vec3(0,0,0); + + for (int s = 0; s < samples; ++s) + { + vec3 pos = getPosition(itc, s).xyz; + if (pos.z >= far_z) + { + vec3 norm = texelFetch(normalMap, itc, s).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = normalize(norm); + vec4 spec = texelFetch(specularRect, itc, s); + vec3 diff = texelFetch(diffuseRect, itc, s).rgb; + float noise = texture2D(noiseMap, frag.xy/128.0).b; + vec3 out_col = vec3(0,0,0); + vec3 npos = normalize(-pos); + + // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop + for (int i = 0; i < MAX_LIGHT_COUNT; ++i) + { + bool light_contrib = (i < light_count); + + vec3 lv = light[i].xyz-pos; + float dist2 = dot(lv,lv); + dist2 /= light[i].w; + if (dist2 > 1.0) + { + light_contrib = false; + } + + float da = dot(norm, lv); + if (da < 0.0) + { + light_contrib = false; + } + + if (light_contrib) + { + lv = normalize(lv); + da = dot(norm, lv); + + float fa = light_col[i].a+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 = 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; + } + } + + fcol += out_col; + ++wght; + } + } + + if (wght <= 0) + { + discard; + } + + gl_FragColor.rgb = fcol/samples; + gl_FragColor.a = 0.0; + + +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl index 2e3e84dd15..434fb6f534 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec4 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index a9f03f7615..0d25d7792d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + //class 1 -- no shadows diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl new file mode 100644 index 0000000000..c80a54346e --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl @@ -0,0 +1,232 @@ +/** + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +//class 1 -- no shadows + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +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 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(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen, sample).r; + vec2 sc = vec2(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() +{ + int wght = 0; + + vec3 fcol = vec3(0,0,0); + + vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; + + ivec2 itc = ivec2(frag.xy); + + for (int i = 0; i < samples; ++i) + { + vec3 pos = getPosition(itc, i).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 <= 1.0) + { + vec3 norm = texelFetch(normalMap, itc, i).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) + { + 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) + { + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texelFetch(diffuseRect, itc, i).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 = texelFetch(specularRect, itc, i); + 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; + } + } + } + } + + fcol += col; + ++wght; + } + } + } + } + + if (wght <= 0) + { + discard; + } + + gl_FragColor.rgb = fcol/samples; + 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 22ed9dcd40..5efa3200d4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ - #version 120 + #extension GL_ARB_texture_rectangle : enable @@ -30,7 +30,7 @@ uniform vec4 viewport; vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = (pos_screen.xy-viewport.xy)*2.0; sc /= viewport.zw; sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl new file mode 100644 index 0000000000..feaf38115d --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl @@ -0,0 +1,108 @@ +/** + * @file pointLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS depthMap; +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS normalMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + + +uniform vec3 env_mat[3]; +uniform float sun_wash; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; +uniform vec4 viewport; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen, sample).r; + vec2 sc = (vec2(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() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + ivec2 itc = ivec2(frag.xy); + + int wght = 0; + vec3 fcol = vec3(0,0,0); + + for (int s = 0; s < samples; ++s) + { + vec3 pos = getPosition(itc, s).xyz; + vec3 lv = vary_light.xyz-pos; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 <= 1.0) + { + vec3 norm = texelFetch(normalMap, itc, s).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + float da = dot(norm, lv); + if (da >= 0.0) + { + norm = normalize(norm); + lv = normalize(lv); + da = dot(norm, lv); + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + + vec3 col = texelFetch(diffuseRect, itc, s).rgb; + float fa = gl_Color.a+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 = texelFetch(specularRect, itc, s); + if (spec.a > 0.0) + { + 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; + } + } + + fcol += col; + ++wght; + } + } + } + + if (wght <= 0) + { + discard; + } + + gl_FragColor.rgb = fcol/samples; + 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 8e74feb615..c510d8ad77 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -5,19 +5,14 @@ * $/LicenseInfo$ */ -#version 120 + varying vec4 vary_light; varying vec4 vary_fragcoord; -uniform vec2 screen_res; -uniform float near_clip; - void main() { //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; vary_fragcoord = pos; @@ -25,6 +20,8 @@ void main() tex.w = 1.0; vary_light = gl_MultiTexCoord0; + + gl_Position = pos; gl_FrontColor = gl_Color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 77f1b2224c..f6b0402bb9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -29,7 +29,7 @@ varying vec2 vary_fragcoord; float getDepth(vec2 pos_screen) { - float z = texture2DRect(depthMap, pos_screen.xy).a; + float z = texture2DRect(depthMap, pos_screen.xy).r; z = z*2.0-1.0; vec4 ndc = vec4(0.0, 0.0, z, 1.0); vec4 p = inv_proj*ndc; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl new file mode 100644 index 0000000000..62ae5f917a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl @@ -0,0 +1,133 @@ +/** + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS edgeMap; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2D bloomMap; + +uniform float depth_cutoff; +uniform float norm_cutoff; +uniform float focal_distance; +uniform float blur_constant; +uniform float tan_pixel_angle; +uniform float magnification; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec2 vary_fragcoord; + +vec4 texture2DMS(sampler2DMS tex, ivec2 tc) +{ + vec4 ret = vec4(0,0,0,0); + for (int i = 0; i < samples; ++i) + { + ret += texelFetch(tex, tc, i); + } + + return ret/samples; +} + +float getDepth(ivec2 pos_screen) +{ + float z = texture2DMS(depthMap, pos_screen.xy).r; + 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; +} + +float calc_cof(float depth) +{ + float sc = abs(depth-focal_distance)/-depth*blur_constant; + + sc /= magnification; + + // tan_pixel_angle = pixel_length/-depth; + float pixel_length = tan_pixel_angle*-focal_distance; + + sc = sc/pixel_length; + sc *= 1.414; + + return sc; +} + +void dofSample(inout vec4 diff, inout float w, float min_sc, float cur_depth, ivec2 tc) +{ + float d = getDepth(tc); + + float sc = calc_cof(d); + + if (sc > min_sc //sampled pixel is more "out of focus" than current sample radius + || d < cur_depth) //sampled pixel is further away than current pixel + { + float wg = 0.25; + + vec4 s = texture2DMS(diffuseRect, tc); + // de-weight dull areas to make highlights 'pop' + wg += s.r+s.g+s.b; + + diff += wg*s; + + w += wg; + } +} + + +void main() +{ + ivec2 itc = ivec2(vary_fragcoord.xy); + + vec3 norm = texture2DMS(normalMap, itc).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + + float depth = getDepth(itc); + + vec4 diff = texture2DMS(diffuseRect, itc); + + { + float w = 1.0; + + float sc = calc_cof(depth); + sc = min(abs(sc), 10.0); + + float fd = depth*0.5f; + + float PI = 3.14159265358979323846264; + + int isc = int(sc); + + // sample quite uniformly spaced points within a circle, for a circular 'bokeh' + //if (depth < focal_distance) + { + for (int x = -isc; x <= isc; x+=2) + { + for (int y = -isc; y <= isc; y+=2) + { + ivec2 cur_samp = ivec2(x,y); + float cur_sc = length(vec2(cur_samp)); + if (cur_sc < sc) + { + dofSample(diff, w, cur_sc, depth, itc+cur_samp); + } + } + } + } + + diff /= w; + } + + vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); + gl_FragColor = diff + bloom; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index ab48d08bbb..bf829bfc56 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl new file mode 100644 index 0000000000..bf35dfe11c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl @@ -0,0 +1,37 @@ +/** + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2D bloomMap; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +vec4 texture2DMS(sampler2DMS tex, ivec2 tc) +{ + vec4 ret = vec4(0,0,0,0); + + for (int i = 0; i < samples; ++i) + { + ret += texelFetch(tex,tc,i); + } + + return ret/samples; +} + +void main() +{ + vec4 diff = texture2DMS(diffuseRect, ivec2(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 index 12983baa94..876f65ee3a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl index 63b3c9f205..fa3f04bcc8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl index ae57227fe5..eebe930666 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; uniform vec2 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 6674c4a5aa..e0c5406483 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index db3bddc6be..9271a5115c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec4 post_pos; diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl new file mode 100644 index 0000000000..820c82ffd7 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -0,0 +1,44 @@ +/** + * @file WLSkyF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +///////////////////////////////////////////////////////////////////////// +// The fragment shader for the sky +///////////////////////////////////////////////////////////////////////// + +varying vec4 vary_HazeColor; + +uniform sampler2D cloud_noise_texture; +uniform vec4 gamma; + +/// Soft clips the light with a gamma correction +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() +{ + // Potential Fill-rate optimization. Add cloud calculation + // back in and output alpha of 0 (so that alpha culling kills + // the fragment) if the sky wouldn't show up because the clouds + // are fully opaque. + + vec4 color; + color = vary_HazeColor; + color *= 2.; + + /// Gamma correct for WL (soft clip effect). + gl_FragData[0] = vec4(scaleSoftClip(color.rgb), 1.0); + gl_FragData[1] = vec4(0.0,0.0,0.0,0.0); + gl_FragData[2] = vec4(0,0,1,0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl new file mode 100644 index 0000000000..1ea00f723a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -0,0 +1,140 @@ +/** + * @file WLSkyV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +// SKY //////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +// Output parameters +varying vec4 vary_HazeColor; + +// Inputs +uniform vec3 camPosLocal; + +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 max_y; + +uniform vec4 glow; + +uniform vec4 cloud_color; + +uniform vec4 cloud_scale; + +void main() +{ + + // World / view / projection + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; + + // Get relative position + vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0); + //vec3 P = gl_Vertex.xyz + vec3(0,50,0); + + // Set altitude + if (P.y > 0.) + { + P *= (max_y.x / P.y); + } + else + { + P *= (-32000. / P.y); + } + + // Can normalize then + vec3 Pn = normalize(P); + float Plen = length(P); + + // Initialize temp variables + vec4 temp1 = vec4(0.); + vec4 temp2 = vec4(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 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + + // Calculate relative weights + temp1 = blue_density + haze_density.x; + blue_weight = blue_density / temp1; + haze_weight = haze_density.x / temp1; + + // Compute sunlight from P & lightnorm (for long rays like sky) + temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // Distance + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z); + + + // Compute haze glow + temp2.x = dot(Pn, lightnorm.xyz); + temp2.x = 1. - temp2.x; + // temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .001); + // 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; + + + // Haze color above cloud + vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient) + + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + ambient) + ); + + + // Increase ambient when there are more clouds + vec4 tmpAmbient = ambient; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5; + + // Dim sunlight by cloud shadow percentage + sunlight *= (1. - cloud_shadow.x); + + // Haze color below cloud + vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) + ); + + // Final atmosphere additive + vary_HazeColor *= (1. - temp1); + + // Attenuate cloud color by atmosphere + temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds + + // At horizon, blend high altitude sky color towards the darker color below the clouds + vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1)); + + // won't compile on mac without this being set + //vary_AtmosAttenuation = vec3(0.0,0.0,0.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 29340c7e9f..60082f40d6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -259,7 +259,7 @@ vec3 scaleSoftClip(vec3 light) void main() { vec2 tc = vary_fragcoord.xy; - float depth = texture2DRect(depthMap, tc.xy).a; + float depth = texture2DRect(depthMap, tc.xy).r; 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 diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl new file mode 100644 index 0000000000..9dfacfb520 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl @@ -0,0 +1,318 @@ +/** + * @file softenLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS normalMap; +uniform sampler2DMS depthMap; +uniform sampler2D noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D lightFunc; + +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 mat4 shadow_matrix[3]; +//uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +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; +} + +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; +} + +vec4 texture2DMS(sampler2DMS tex, ivec2 tc) +{ + vec4 ret = vec4(0,0,0,0); + + for (int i = 0; i < samples; ++i) + { + ret += texelFetch(tex,tc,i); + } + + return ret/samples; +} + +void main() +{ + vec2 tc = vary_fragcoord.xy; + ivec2 itc = ivec2(tc); + + vec3 fcol = vec3(0,0,0); + + for (int i = 0; i < samples; ++i) + { + float depth = texelFetch(depthMap, itc, i).r; + vec3 pos = getPosition_d(tc, depth).xyz; + vec3 norm = texelFetch(normalMap, itc, i).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 = texelFetch(diffuseRect, itc, i); + if (diffuse.a >= 1.0) + { + fcol += diffuse.rgb; + } + else + { + vec4 spec = texelFetch(specularRect, itc, i); + + calcAtmospherics(pos.xyz, 1.0); + + vec3 col = atmosAmbient(vec3(0)); + col += atmosAffectDirectionalLight(max(min(da, 1.0), 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*texture2D(lightFunc, vec2(sa, spec.a)).a; + + // add the two types of shiny together + col += dumbshiny * spec.rgb; + } + + col = atmosLighting(col); + col = scaleSoftClip(col); + fcol += col; + } + } + + gl_FragColor.rgb = fcol.rgb/samples; + gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl index 8f0bcca76b..745cc01992 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 index 29fac46bfe..9aaffc15bf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl new file mode 100644 index 0000000000..4bb9bad275 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl @@ -0,0 +1,234 @@ +/** + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +//class 1 -- no shadows + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +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(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen, sample).r; + vec2 sc = vec2(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; + ivec2 itc = ivec2(frag.xy); + + vec3 fcol = vec3(0,0,0); + int wght = 0; + + for (int i = 0; i < samples; ++i) + { + vec3 pos = getPosition(itc, i).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 <= 1.0) + { + vec3 norm = texelFetch(normalMap, itc, i).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) + { + 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) + { + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texelFetch(diffuseRect, itc, i).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 = texelFetch(specularRect, itc, i); + 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; + } + } + } + } + + fcol += col; + ++wght; + } + } + } + } + + if (wght <= 0) + { + discard; + } + + gl_FragColor.rgb = fcol/samples; + gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl new file mode 100644 index 0000000000..2cf7d194cc --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl @@ -0,0 +1,19 @@ +/** + * @file starsF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +uniform sampler2D diffuseMap; + +void main() +{ + vec4 col = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + + gl_FragData[0] = col; + gl_FragData[1] = vec4(0,0,0,0); + gl_FragData[2] = vec4(0,0,1,0); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl new file mode 100644 index 0000000000..c43125dad9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl @@ -0,0 +1,17 @@ +/** + * @file starsV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + + +void main() +{ + //transform vertex + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index 00093836a2..f20886565a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + //class 1, no shadow, no SSAO, should never be called diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl new file mode 100644 index 0000000000..f20886565a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl @@ -0,0 +1,17 @@ +/** + * @file sunLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +//class 1, no shadow, no SSAO, should never be called + +#extension GL_ARB_texture_rectangle : enable + +void main() +{ + 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 index cd91351ad4..665d8126a0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -35,7 +35,7 @@ uniform float shadow_offset; vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = pos_screen.xy*2.0; sc /= screen_res; sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl new file mode 100644 index 0000000000..32d1b2149a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl @@ -0,0 +1,123 @@ +/** + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 1 -- no shadow, SSAO only + +uniform sampler2DMS depthMap; +uniform sampler2DMS 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(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen, sample).r; + 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, int sample) +{ + float ret = 1.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++) + { + ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect)); + vec3 samppos_world = getPosition(samppos_screen, sample).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) + + 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)); + + return min(ret, 1.0); +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + ivec2 itc = ivec2(pos_screen); + + float col = 0; + + for (int i = 0; i < samples; i++) + { + vec4 pos = getPosition(itc, i); + vec3 norm = texelFetch(normalMap, itc, i).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + col += calcAmbientOcclusion(pos,norm,i); + } + + col /= samples; + + gl_FragColor[0] = 1.0; + gl_FragColor[1] = col; + 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 9beb513ad8..814deb3677 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 0edae47918..d005f67bf6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D detail_0; uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index a6163063be..3038fd2966 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index c54d9a1e3e..de7e038402 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index 29689ecbaf..a9bef4292d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index e76f598d09..2710422d32 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl index 649e392630..5397290b11 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 f2023fa5ea..32f5f5f236 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl new file mode 100644 index 0000000000..9267a8585d --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl @@ -0,0 +1,38 @@ +/** + * @file glowExtractF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseMap; +uniform float minLuminance; +uniform float maxExtractAlpha; +uniform vec3 lumWeights; +uniform vec3 warmthWeights; +uniform float warmthAmount; + +void main() +{ + ivec2 itc = ivec2(gl_TexCoord[0].xy); + vec4 fcol = vec4(0,0,0,0); + + for (int i = 0; i < samples; i++) + { + vec4 col = texelFetch(diffuseMap, itc, i); + + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) ); + float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) ); + + fcol += vec4(col.rgb, max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha)); + } + + gl_FragColor = fcol/samples; +} diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl index 0ca0608b45..76736fed53 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + void main() { diff --git a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl index 65fc2e9f99..d3225546b3 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; uniform float glowStrength; diff --git a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl index 0bd44cec90..9bb41626ae 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 ac00f15b35..cdc2ca3da2 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 1e19ee7699..8af981915b 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 34f78565a5..d94d986581 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 0dfac84a6e..06854fcc0a 100644 --- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 4e9c09b1ea..0f24e3c35a 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 a34cf23790..630459b324 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 161c794c68..831d6a761c 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 6f821f893d..f6c6d945de 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 d1c98bf70c..f114f766bf 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 9c59e8c3ad..1796730c92 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 1fee99c446..bfe0be9fdf 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 fb5da21c72..6f1fe91007 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 index 1bdaccf9b8..19072cd052 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl @@ -6,7 +6,7 @@ */ -#version 120 + uniform sampler2D diffuseMap; uniform samplerCube environmentMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl index 2e94d3bbf1..0ae6dc89e2 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl @@ -6,7 +6,7 @@ */ -#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 714f9a2551..5d4bf2c33e 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 65b45f8081..574252af12 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + float calcDirectionalLight(vec3 n, vec3 l) diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl index 7f65ea76f7..29f575b7e5 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 8f13e6dc04..65da5a6825 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 56f31f6a79..d491f1102e 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 64d549ff52..ef38ee9699 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 c5d084c132..286c92326b 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 732d246471..772a420e33 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); vec3 atmosAmbient(vec3 light); diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl index 73e1a1ec26..da60a3ddf5 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 afc3dc89bf..c0b72115dd 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 3dc4294f67..391c06edc8 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + void fullbright_shiny_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl index f0baeeeee5..f44a5ce32e 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + void calcAtmospherics(vec3 inPositionEye); mat4 getObjectSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl index 02367b9439..31e0f0a429 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 index 5daf66fb31..8ffb252f57 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + void fullbright_shiny_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl index 02ff3cc2a9..e5dafa8c78 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + void calcAtmospherics(vec3 inPositionEye); mat4 getObjectSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl index 38e07dbd80..3382384c99 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 afaac4f69c..220f26614f 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 2cf7a69baa..d079de5377 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + void shiny_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl index 4146646058..cd655f3bb5 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl @@ -5,7 +5,7 @@ * $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/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl index 6ea83b721d..68a086dbc1 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 e3babe2210..4649d1c47c 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 d449d37c0c..b4e4dcfbbf 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl @@ -5,8 +5,6 @@ * $/LicenseInfo$ */ -#version 120 - void default_lighting(); void main() diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl index be38a14d52..900448035c 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl @@ -5,7 +5,7 @@ * $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/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl index 0d8e14e2e3..b493f76fcc 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 68bd81e029..4ec5ee43b4 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 f337bde329..3d05850ab3 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 4b402a7028..f1a0af21af 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 20948b1e46..73bbd57315 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 8a2c2a7186..e0eb7b3767 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 a1dd4ed5fe..a251213ff5 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 7aed1fd3b5..4958cb2f72 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 6780dc4d3e..75929bc609 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 172c2ca078..3e8b719f93 100644 --- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl +++ b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 index 6dfc1b952c..681e52de2a 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -5,11 +5,10 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable -uniform sampler2D diffuseMap; uniform sampler2DRectShadow shadowMap0; uniform sampler2DRectShadow shadowMap1; uniform sampler2DRectShadow shadowMap2; @@ -105,7 +104,7 @@ void main() } } - vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 diff = diffuseLookup(gl_TexCoord[0].xy); vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a); vec4 color = diff * col; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl new file mode 100644 index 0000000000..5350359f75 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -0,0 +1,125 @@ +/** + * @file alphaF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DRect depthMap; +uniform sampler2D diffuseMap; + +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,shadow,1,1); + +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl index d227346163..948a52da5b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); @@ -35,19 +35,24 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa //get distance float d = length(lv); - //normalize light vector - lv *= 1.0/d; + float da = 0.0; + + if (d > 0.0 && la > 0.0 && fa > 0.0) + { + //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); + //distance attenuation + float dist2 = d*d/(la*la); + 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 + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 - //angular attenuation - da *= calcDirectionalLight(n, lv); + //angular attenuation + da *= calcDirectionalLight(n, lv); + } return da; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index 86f014df35..f616ecc872 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); @@ -22,6 +22,7 @@ varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; varying vec3 vary_pointlight_col; +varying float vary_texture_index; uniform float near_clip; uniform float shadow_offset; @@ -35,19 +36,24 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa //get distance float d = length(lv); - //normalize light vector - lv *= 1.0/d; + float da = 0.0; + + if (d > 0.0 && la > 0.0 && fa > 0.0) + { + //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); + //distance attenuation + float dist2 = d*d/(la*la); + 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 + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 - //angular attenuation - da *= calcDirectionalLight(n, lv); + //angular attenuation + da *= calcDirectionalLight(n, lv); + } return da; } @@ -55,11 +61,13 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa void main() { //transform vertex - gl_Position = ftransform(); + vec4 vert = vec4(gl_Vertex.xyz, 1.0); + vary_texture_index = gl_Vertex.w; + gl_Position = gl_ModelViewProjectionMatrix * vert; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vec4 pos = (gl_ModelViewMatrix * vert); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); @@ -94,7 +102,7 @@ void main() gl_FogFragCoord = pos.z; - pos = gl_ModelViewProjectionMatrix * gl_Vertex; + pos = gl_ModelViewProjectionMatrix * vert; vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl index 495e86c8db..01e40afc4f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); @@ -37,19 +37,24 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa //get distance float d = length(lv); - //normalize light vector - lv *= 1.0/d; + float da = 0.0; + + if (d > 0.0 && la > 0.0 && fa > 0.0) + { + //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); + //distance attenuation + float dist2 = d*d/(la*la); + 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 + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 - //angular attenuation - da *= calcDirectionalLight(n, lv); + //angular attenuation + da *= calcDirectionalLight(n, lv); + } return da; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl index 3155f3f929..729e4b5543 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -22,7 +22,7 @@ uniform vec2 screen_res; float getDepth(vec2 pos_screen) { - float z = texture2DRect(depthMap, pos_screen.xy).a; + float z = texture2DRect(depthMap, pos_screen.xy).r; z = z*2.0-1.0; vec4 ndc = vec4(0.0, 0.0, z, 1.0); vec4 p = inv_proj*ndc; diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl new file mode 100644 index 0000000000..b22bc5b288 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl @@ -0,0 +1,74 @@ +/** + * @file edgeF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; + +varying vec2 vary_fragcoord; + +uniform float depth_cutoff; +uniform float norm_cutoff; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +float getDepth(ivec2 pos_screen, int sample) +{ + float z = texelFetch(depthMap, pos_screen, sample).r; + 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() +{ + float e = 0; + + ivec2 itc = ivec2(vary_fragcoord.xy); + + for (int i = 0; i < samples; i++) + { + vec3 norm = texelFetch(normalMap, itc, i).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + float depth = getDepth(itc, i); + + vec2 tc = vary_fragcoord.xy; + + int sc = 1; + + vec2 de; + de.x = (depth-getDepth(itc+ivec2(sc, sc),i)) + (depth-getDepth(itc+ivec2(-sc, -sc), i)); + de.y = (depth-getDepth(itc+ivec2(-sc, sc),i)) + (depth-getDepth(itc+ivec2(sc, -sc), i)); + de /= depth; + de *= de; + de = step(depth_cutoff, de); + + vec2 ne; + vec3 nexnorm = texelFetch(normalMap, itc+ivec2(-sc,-sc), i).rgb; + nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm + ne.x = dot(nexnorm, norm); + vec3 neynorm = texelFetch(normalMap, itc+ivec2(sc,sc), i).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); + + e += dot(de,de)+dot(ne,ne); + } + + e /= samples; + + gl_FragColor.a = e; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl index b3413c301f..393084a3db 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index d6cd984ebe..f54186ffca 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -91,7 +91,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = pos_screen.xy*2.0; sc /= screen_res; sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl new file mode 100644 index 0000000000..fee32be3e3 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl @@ -0,0 +1,244 @@ +/** + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +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(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen, sample).r; + vec2 sc = vec2(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() +{ + int wght = 0; + + vec3 fcol = vec3(0,0,0); + + vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; + + ivec2 itc = ivec2(frag.xy); + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + for (int i = 0; i < samples; i++) + { + vec3 pos = getPosition(itc, i).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 <= 1.0) + { + vec3 norm = texelFetch(normalMap, itc, i).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) + { + 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) + { + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texelFetch(diffuseRect, itc, i).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 = texelFetch(specularRect, itc, i); + 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; + } + } + } + } + + fcol += col; + wght++; + } + } + } + } + + if (wght <= 0) + { + discard; + } + + gl_FragColor.rgb = fcol/samples; + gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 0160e84278..66a1a8515f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -71,7 +71,7 @@ vec4 getPosition_d(vec2 pos_screen, float depth) 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; + float depth = texture2DRect(depthMap, pos_screen.xy).r; return getPosition_d(pos_screen, depth); } @@ -258,7 +258,7 @@ vec3 scaleSoftClip(vec3 light) void main() { vec2 tc = vary_fragcoord.xy; - float depth = texture2DRect(depthMap, tc.xy).a; + float depth = texture2DRect(depthMap, tc.xy).r; 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 @@ -288,54 +288,8 @@ void main() 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 += dumbshiny * spec.rgb; } col = atmosLighting(col); diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl new file mode 100644 index 0000000000..0bae10ca7d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl @@ -0,0 +1,307 @@ +/** + * @file softenLightMSF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS normalMap; +uniform sampler2DRect lightMap; +uniform sampler2DMS 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; +} + +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; + ivec2 itc = ivec2(tc); + + vec3 fcol = vec3(0,0,0); + + vec2 scol_ambocc = texture2DRect(lightMap, tc).rg; + float ambocc = scol_ambocc.g; + + for (int i = 0; i < samples; ++i) + { + float depth = texelFetch(depthMap, itc.xy, i).r; + vec3 pos = getPosition_d(tc, depth).xyz; + vec3 norm = texelFetch(normalMap, itc, i).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + + float da = max(dot(norm.xyz, vary_light.xyz), 0.0); + + vec4 diffuse = texelFetch(diffuseRect, itc, i); + vec4 spec = texelFetch(specularRect, itc, i); + + float amb = 0; + + float scol = max(scol_ambocc.r, diffuse.a); + amb += ambocc; + + 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; + + // add the two types of shiny together + col += dumbshiny * spec.rgb; + } + + col = atmosLighting(col); + col = scaleSoftClip(col); + + fcol += col; + } + + gl_FragColor.rgb = fcol/samples; + 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 index 8f0bcca76b..745cc01992 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 50b9ef276e..cd3828fbd4 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl new file mode 100644 index 0000000000..ec9b547a47 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl @@ -0,0 +1,245 @@ +/** + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +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(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen, sample).r; + vec2 sc = vec2(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; + ivec2 itc = ivec2(frag.xy); + + vec3 fcol = vec3(0,0,0); + int wght = 0; + + 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); + } + + for (int i = 0; i < samples; i++) + { + vec3 pos = getPosition(itc, i).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 <= 1.0) + { + vec3 norm = texelFetch(normalMap, itc, i).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) + { + 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) + { + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texelFetch(diffuseRect, itc, i).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 = texelFetch(specularRect, itc, i); + 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; + } + } + } + } + + fcol += col; + wght++; + } + } + } + } + + if (wght <= 0) + { + discard; + } + + gl_FragColor.rgb = fcol/wght; + 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 index 4369b3b34f..315139b415 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -45,7 +45,7 @@ uniform float spot_shadow_offset; vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = pos_screen.xy*2.0; sc /= screen_res; sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl new file mode 100644 index 0000000000..63d13c996d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl @@ -0,0 +1,202 @@ +/** + * @file sunLightMSF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 2, shadows, no SSAO + +uniform sampler2DMS depthMap; +uniform sampler2DMS 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(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen.xy, sample).r; + vec2 sc = vec2(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; + ivec2 itc = ivec2(pos_screen); + + //try doing an unproject here + + vec4 fcol = vec4(0,0,0,0); + + for (int i = 0; i < samples; i++) + { + vec4 pos = getPosition(itc, i); + + vec4 nmap4 = texelFetch(normalMap, itc, i); + 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; + } + + fcol[0] += shadow; + fcol[1] += 1.0; + + spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); + + //spotlight shadow 1 + vec4 lpos = shadow_matrix[4]*spos; + fcol[2] += pcfShadow(shadowMap4, lpos, 0.8); + + //spotlight shadow 2 + lpos = shadow_matrix[5]*spos; + fcol[3] += pcfShadow(shadowMap5, lpos, 0.8); + } + + gl_FragColor = fcol/samples; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 847b36b1ac..d53850b489 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable @@ -45,7 +45,7 @@ uniform float spot_shadow_offset; vec4 getPosition(vec2 pos_screen) { - float depth = texture2DRect(depthMap, pos_screen.xy).a; + float depth = texture2DRect(depthMap, pos_screen.xy).r; vec2 sc = pos_screen.xy*2.0; sc /= screen_res; sc -= vec2(1.0,1.0); @@ -234,7 +234,7 @@ void main() gl_FragColor[0] = shadow; gl_FragColor[1] = calcAmbientOcclusion(pos, norm); - spos.xyz = shadow_pos+offset*spot_shadow_offset; + spos.xyz = shadow_pos+norm*spot_shadow_offset; //spotlight shadow 1 vec4 lpos = shadow_matrix[4]*spos; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl new file mode 100644 index 0000000000..a2a76eed9f --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl @@ -0,0 +1,241 @@ +/** + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 2 -- shadows and SSAO + +uniform sampler2DMS depthMap; +uniform sampler2DMS 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(ivec2 pos_screen, int sample) +{ + float depth = texelFetch(depthMap, pos_screen, sample).r; + vec2 sc = vec2(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, int sample) +{ + float ret = 1.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++) + { + ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect)); + vec3 samppos_world = getPosition(samppos_screen, sample).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) + + 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)); + + 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; + ivec2 itc = ivec2(pos_screen); + vec4 fcol = vec4(0,0,0,0); + + for (int i = 0; i < samples; i++) + { + vec4 pos = getPosition(itc, i); + + vec4 nmap4 = texelFetch(normalMap, itc, i); + nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + float displace = nmap4.w; + vec3 norm = nmap4.xyz; + + 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); + + } + } + else + { + // more distant than the shadow map covers + shadow = 1.0; + } + + + fcol[0] += shadow; + fcol[1] += calcAmbientOcclusion(pos, norm, i); + + spos.xyz = shadow_pos+offset*spot_shadow_offset; + + //spotlight shadow 1 + vec4 lpos = shadow_matrix[4]*spos; + fcol[2] += pcfShadow(shadowMap4, lpos, 0.8); + + //spotlight shadow 2 + lpos = shadow_matrix[5]*spos; + fcol[3] += pcfShadow(shadowMap5, lpos, 0.8); + } + + gl_FragColor = fcol / samples; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl index 9beb513ad8..814deb3677 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec4 vary_light; varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl index a4ad0bfa15..dff4d4a68f 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2DRect RenderTexture; uniform float bloomStrength; diff --git a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl index d471a6c5e5..de469542f9 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 66880b958e..8871bb3fc7 100644 --- a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2DRect RenderTexture; uniform float brightness; diff --git a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl index c35c500d62..9c52b8dd5d 100644 --- a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 e77baa5bee..713f8021de 100644 --- a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2DRect RenderTexture; uniform float extractLow; diff --git a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl index 8e0eec6f5e..fd94b2e95f 100644 --- a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2DRect RenderTexture; uniform sampler2D NoiseTexture; diff --git a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl index 98a50e22fc..a1a9c9716c 100644 --- a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + 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 bbb8951f3a..9527dc469b 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 84906c16bf..2658bee88d 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 7590c542ef..974e227b77 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 900f1a6cb8..702e0881ac 100644 --- a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 f4f6b6e90f..c4e4bc08c5 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 9f3328cbf0..b66b72b401 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 342bc2ab66..4c31602736 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl @@ -5,16 +5,14 @@ * $/LicenseInfo$ */ -#version 120 -uniform sampler2D diffuseMap; vec3 atmosLighting(vec3 light); vec3 scaleSoftClip(vec3 light); void default_lighting() { - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color; color.rgb = atmosLighting(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl index dad18b5883..95bd052b5d 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl @@ -5,16 +5,14 @@ * $/LicenseInfo$ */ -#version 120 -uniform sampler2D diffuseMap; vec3 fullbrightAtmosTransport(vec3 light); vec3 fullbrightScaleSoftClip(vec3 light); void fullbright_lighting() { - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color; color.rgb = fullbrightAtmosTransport(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl new file mode 100644 index 0000000000..b1e61e1a33 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl @@ -0,0 +1,25 @@ +/** + * @file lightFullbrightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +vec3 fullbrightAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +uniform sampler2D diffuseMap; + +void fullbright_lighting() +{ + vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; + + color.rgb = fullbrightAtmosTransport(color.rgb); + + color.rgb = fullbrightScaleSoftClip(color.rgb); + + gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl index 73ff81e03a..26f0ea84e0 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl @@ -5,9 +5,8 @@ * $/LicenseInfo$ */ -#version 120 -uniform sampler2D diffuseMap; + uniform samplerCube environmentMap; vec3 fullbrightShinyAtmosTransport(vec3 light); @@ -15,7 +14,7 @@ vec3 fullbrightScaleSoftClip(vec3 light); void fullbright_shiny_lighting() { - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 color = diffuseLookup(gl_TexCoord[0].xy); color.rgb *= gl_Color.rgb; vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl new file mode 100644 index 0000000000..953298da0d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl @@ -0,0 +1,32 @@ +/** + * @file lightFullbrightShinyF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +void fullbright_shiny_lighting() +{ + 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 = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl index 9b4b584369..a6e10a249d 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl @@ -5,9 +5,9 @@ * $License$ */ -#version 120 -uniform sampler2D diffuseMap; + + uniform samplerCube environmentMap; vec3 fullbrightShinyAtmosTransport(vec3 light); @@ -16,7 +16,7 @@ vec4 applyWaterFog(vec4 color); void fullbright_shiny_lighting_water() { - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 color = diffuseLookup(gl_TexCoord[0].xy); color.rgb *= gl_Color.rgb; vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl new file mode 100644 index 0000000000..b4bb665a2b --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl @@ -0,0 +1,32 @@ +/** + * @file lightFullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + + + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +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 3d46c8d874..887d4130e7 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl @@ -5,16 +5,16 @@ * $/LicenseInfo$ */ -#version 120 -uniform sampler2D diffuseMap; + +vec4 diffuseLookup(vec2 texcoord); vec3 fullbrightAtmosTransport(vec3 light); vec4 applyWaterFog(vec4 color); void fullbright_lighting_water() { - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color; color.rgb = fullbrightAtmosTransport(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl new file mode 100644 index 0000000000..1234682ae9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl @@ -0,0 +1,23 @@ +/** + * @file lightFullbrightWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +uniform sampler2D diffuseMap; + +vec3 fullbrightAtmosTransport(vec3 light); +vec4 applyWaterFog(vec4 color); + +void fullbright_lighting_water() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + + color.rgb = fullbrightAtmosTransport(color.rgb); + + gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl new file mode 100644 index 0000000000..149cf791f5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl @@ -0,0 +1,25 @@ +/** + * @file lightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +uniform sampler2D diffuseMap; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +void default_lighting() +{ + vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl index ebe21320b4..300fcac092 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl @@ -5,9 +5,9 @@ * $/LicenseInfo$ */ -#version 120 -uniform sampler2D diffuseMap; + + uniform samplerCube environmentMap; vec3 scaleSoftClip(vec3 light); @@ -16,7 +16,7 @@ vec4 applyWaterFog(vec4 color); void shiny_lighting() { - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 color = diffuseLookup(gl_TexCoord[0].xy); color.rgb *= gl_Color.rgb; vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl new file mode 100644 index 0000000000..e877c0abb1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl @@ -0,0 +1,32 @@ +/** + * @file lightShinyF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +vec3 scaleSoftClip(vec3 light); +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void shiny_lighting() +{ + 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 = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + color.a = max(color.a, gl_Color.a); + gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl index 7f48e2cf1d..07572fa915 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl @@ -5,10 +5,9 @@ * $/LicenseInfo$ */ -#version 120 -uniform sampler2D diffuseMap; + uniform samplerCube environmentMap; vec3 atmosLighting(vec3 light); @@ -16,7 +15,7 @@ vec4 applyWaterFog(vec4 color); void shiny_lighting_water() { - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 color = diffuseLookup(gl_TexCoord[0].xy); color.rgb *= gl_Color.rgb; vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl new file mode 100644 index 0000000000..3904179427 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl @@ -0,0 +1,29 @@ +/** + * @file lightShinyWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void 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 = atmosLighting(color.rgb); + color.a = max(color.a, gl_Color.a); + gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl index ad1dc4da77..3384f64d07 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 a0f6e019ef..10c770fcc2 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 97eba92d7b..61341a9f1f 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl @@ -5,16 +5,14 @@ * $/LicenseInfo$ */ -#version 120 -uniform sampler2D diffuseMap; vec3 atmosLighting(vec3 light); vec4 applyWaterFog(vec4 color); void default_lighting_water() { - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color; color.rgb = atmosLighting(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl new file mode 100644 index 0000000000..ba850b61d0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl @@ -0,0 +1,23 @@ +/** + * @file lightWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +uniform sampler2D diffuseMap; + +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void default_lighting_water() +{ + vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; + + color.rgb = atmosLighting(color.rgb); + + gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl index fde32ed035..8df2e6f222 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 8fe49e3be0..3d43a1813a 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + float calcDirectionalLight(vec3 n, vec3 l); float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); diff --git a/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl new file mode 100644 index 0000000000..f49e74406f --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl @@ -0,0 +1,35 @@ +/** + * @file fullbrightShinyV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec4 origin; + +varying float vary_texture_index; + +void main() +{ + //transform vertex + vec4 vert = vec4(gl_Vertex.xyz,1.0); + vary_texture_index = gl_Vertex.w; + gl_Position = gl_ModelViewProjectionMatrix*vert; + + vec4 pos = (gl_ModelViewMatrix * vert); + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + vec3 ref = reflect(pos.xyz, -norm); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0); + + calcAtmospherics(pos.xyz); + + gl_FrontColor = gl_Color; + + gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl new file mode 100644 index 0000000000..3076fa3260 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl @@ -0,0 +1,29 @@ +/** + * @file fullbrightV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +void calcAtmospherics(vec3 inPositionEye); + +varying float vary_texture_index; + +void main() +{ + //transform vertex + vec4 vert = vec4(gl_Vertex.xyz,1.0); + vary_texture_index = gl_Vertex.w; + gl_Position = gl_ModelViewProjectionMatrix*vert; + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vec4 pos = (gl_ModelViewMatrix * vert); + + calcAtmospherics(pos.xyz); + + gl_FrontColor = gl_Color; + + gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl index 4cebb06df0..49992d3535 100644 --- a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl @@ -5,20 +5,24 @@ * $/LicenseInfo$ */ -#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); +varying float vary_texture_index; + uniform vec4 origin; void main() { //transform vertex - gl_Position = ftransform(); + vec4 vert = vec4(gl_Vertex.xyz,1.0); + vary_texture_index = gl_Vertex.w; + gl_Position = gl_ModelViewProjectionMatrix*vert; - vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vec4 pos = (gl_ModelViewMatrix * vert); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); vec3 ref = reflect(pos.xyz, -norm); diff --git a/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl new file mode 100644 index 0000000000..5e02391767 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl @@ -0,0 +1,33 @@ +/** + * @file simpleV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + + + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); + +varying float vary_texture_index; + +void main() +{ + //transform vertex + vec4 vert = vec4(gl_Vertex.xyz,1.0); + vary_texture_index = gl_Vertex.w; + gl_Position = gl_ModelViewProjectionMatrix*vert; + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vec4 pos = (gl_ModelViewMatrix * vert); + + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + + calcAtmospherics(pos.xyz); + + vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + gl_FrontColor = color; + + gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 77d15fba9a..21a0812c1b 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 8c5b864cbe..ab4cf4806d 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 8d365c15ca..b61b0bb396 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 cf9ef30632..3a6585bb33 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 398f1556a0..0f6e231ca6 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 13207997b2..20f907a006 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 267ef36d4d..3eac63076c 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 a658edd21f..6570dcb608 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 77ca4868a6..d14c638130 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 03bca8f27e..1ea00f723a 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 7f1ad4d5b4..28381482c1 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -5,8 +5,6 @@ * $/LicenseInfo$ */ -#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 a003e2a1f1..3d970d252c 100644 --- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 index fc370ef367..498fee7c66 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2DRect giLightMap; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl index ae57227fe5..eebe930666 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl index 951e3e97ae..9896f8dafe 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl index b2f8b2c633..df4c6b3e0a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl index 19c4e07b8b..7e20d71529 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giV.glsl index 8dc1410ea5..e86f2896da 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl index 5f3bf68b24..980def6443 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl index a24eda35dc..9afeac6ddf 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl index ab99a88971..6d4c20f68c 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl index 12983baa94..876f65ee3a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl index f037754708..fc65881680 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl index ae57227fe5..eebe930666 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index ce32f66000..d38d33cc21 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl index 8f0bcca76b..745cc01992 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl index c54d9a1e3e..de7e038402 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl index 04533fdce1..92347a5b4a 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#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 73bc18b866..24bbc0a1a1 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl @@ -5,7 +5,7 @@ * $/LicenseInfo$ */ -#version 120 + float calcDirectionalLight(vec3 n, vec3 l); float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index dd8a88e558..4da155efda 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 27 +version 29 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -48,6 +48,7 @@ RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 +RenderVBOMappingDisable 1 1 RenderVolumeLODFactor 1 2.0 UseStartScreen 1 1 UseOcclusion 1 1 @@ -64,6 +65,7 @@ RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 +RenderFSAASamples 1 16 // // Low Graphics Settings @@ -95,6 +97,7 @@ SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // Mid Graphics Settings @@ -124,6 +127,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // High Graphics Settings (purty) @@ -153,6 +157,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 4 // // Ultra graphics (REALLY PURTY!) @@ -181,6 +186,8 @@ WLSkyDetail 1 128 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 +RenderFSAASamples 1 8 + // // Class Unknown Hardware (unknown) @@ -238,6 +245,12 @@ RenderDeferred 0 0 RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 +// +// No GL_ARB_map_buffer_range +// +list NoMapBufferRange +RenderVBOMappingDisable 1 0 + // // "Default" setups for safe, low, medium, high @@ -467,7 +480,6 @@ RenderAvatarCloth 0 0 list ATI RenderUseStreamVBO 1 0 -RenderAvatarVP 1 0 // Disable vertex buffer objects by default for ATI cards with little video memory list ATIVramLT256 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 058bdcc730..dab73dc3d1 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 23 +version 25 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -48,6 +48,7 @@ RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 +RenderVBOMappingDisable 1 1 RenderVolumeLODFactor 1 2.0 UseStartScreen 1 1 UseOcclusion 1 1 @@ -62,6 +63,7 @@ RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 +RenderFSAASamples 1 16 // // Low Graphics Settings @@ -93,6 +95,7 @@ SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // Mid Graphics Settings @@ -122,6 +125,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // High Graphics Settings (purty) @@ -151,6 +155,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 4 // // Ultra graphics (REALLY PURTY!) @@ -180,6 +185,7 @@ WLSkyDetail 1 128 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 +RenderFSAASamples 1 8 // // Class Unknown Hardware (unknown) @@ -237,6 +243,13 @@ RenderDeferred 0 0 RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 +// +// No GL_ARB_map_buffer_range +// +list NoMapBufferRange +RenderVBOMappingDisable 1 0 + + // "Default" setups for safe, low, medium, high // diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index c075c660f3..a1e25aae08 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 23 +version 26 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -48,6 +48,7 @@ RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 +RenderVBOMappingDisable 1 1 RenderVolumeLODFactor 1 2.0 UseStartScreen 1 1 UseOcclusion 1 1 @@ -64,6 +65,7 @@ RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 +RenderFSAASamples 1 16 // // Low Graphics Settings @@ -95,6 +97,7 @@ SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // Mid Graphics Settings @@ -124,6 +127,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // High Graphics Settings (purty) @@ -153,6 +157,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 2 +RenderFSAASamples 1 4 // // Ultra graphics (REALLY PURTY!) @@ -182,6 +187,7 @@ WLSkyDetail 1 128 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 2 +RenderFSAASamples 1 8 // // Class Unknown Hardware (unknown) @@ -240,6 +246,13 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 // +// No GL_ARB_map_buffer_range +// +list NoMapBufferRange +RenderVBOMappingDisable 1 0 + + +// // "Default" setups for safe, low, medium, high // list safe @@ -281,6 +294,9 @@ RenderVBOEnable 1 0 list TexUnit8orLess RenderDeferredSSAO 0 0 +list ATI +RenderDeferredSSAO 0 0 + list Intel RenderAnisotropic 1 0 RenderLocalLights 1 0 @@ -409,31 +425,6 @@ Disregard128DefaultDrawDistance 1 0 list ATI_Mobility_Radeon_X1xxx Disregard128DefaultDrawDistance 1 0 - - - -// Avatar hardware skinning causes -// invisible avatars on HD 2600... so I masked -// out other possible bad ones till it's fixed - -list ATI_Radeon_HD_2300 -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_HD_2400 -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_HD_2600 -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -list ATI_Radeon_HD_2900 -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -list ATI_Radeon_HD_3800 -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 - /// Tweaked NVIDIA list NVIDIA_GeForce_FX_5100 diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index 3339172a1a..abe4ec9928 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 27 +version 29 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -48,6 +48,7 @@ RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 +RenderVBOMappingDisable 1 1 RenderVolumeLODFactor 1 2.0 UseStartScreen 1 1 UseOcclusion 1 1 @@ -64,6 +65,7 @@ RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 +RenderFSAASamples 1 16 // // Low Graphics Settings @@ -95,6 +97,7 @@ SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // Mid Graphics Settings @@ -124,6 +127,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // High Graphics Settings (purty) @@ -153,6 +157,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 2 +RenderFSAASamples 1 4 // // Ultra graphics (REALLY PURTY!) @@ -182,6 +187,7 @@ WLSkyDetail 1 128 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 2 +RenderFSAASamples 1 8 // // Class Unknown Hardware (unknown) @@ -240,6 +246,13 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 // +// No GL_ARB_map_buffer_range +// +list NoMapBufferRange +RenderVBOMappingDisable 1 0 + + +// // "Default" setups for safe, low, medium, high // list safe @@ -466,7 +479,6 @@ RenderAvatarCloth 0 0 list ATI RenderUseStreamVBO 1 0 -RenderAvatarVP 1 0 // Disable vertex buffer objects by default for ATI cards with little video memory list ATIVramLT256 diff --git a/indra/newview/groupchatlistener.cpp b/indra/newview/groupchatlistener.cpp index 3758896b85..ef015a950d 100644 --- a/indra/newview/groupchatlistener.cpp +++ b/indra/newview/groupchatlistener.cpp @@ -4,8 +4,25 @@ * @date 2011-04-11 * @brief Implementation for groupchatlistener. * - * $LicenseInfo:firstyear=2011&license=internal$ - * Copyright (c) 2011, Linden Research, Inc. + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/groupchatlistener.h b/indra/newview/groupchatlistener.h index 719e3e877f..0c76db305e 100644 --- a/indra/newview/groupchatlistener.h +++ b/indra/newview/groupchatlistener.h @@ -4,8 +4,25 @@ * @date 2011-04-11 * @brief * - * $LicenseInfo:firstyear=2011&license=internal$ - * Copyright (c) 2011, Linden Research, Inc. + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp new file mode 100644 index 0000000000..a4f5de5632 --- /dev/null +++ b/indra/newview/llaccountingquotamanager.cpp @@ -0,0 +1,278 @@ +/** + * @file LLAccountingQuotaManager.cpp + * @ Handles the setting and accessing for costs associated with mesh + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llaccountingquotamanager.h" +#include "llagent.h" +#include "llviewerregion.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewerparcelmgr.h" +#include "llparcel.h" + +//=============================================================================== +LLAccountingQuotaManager::LLAccountingQuotaManager() +{ +} +//=============================================================================== +class LLAccountingQuotaResponder : public LLCurl::Responder +{ +public: + LLAccountingQuotaResponder( const LLSD& objectIDs ) + : mObjectIDs( objectIDs ) + { + } + + void clearPendingRequests ( void ) + { + for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter ) + { + LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( iter->asUUID() ); + } + } + + void error( U32 statusNum, const std::string& reason ) + { + llwarns << "Transport error "<<reason<<llendl; + //prep#do we really want to remove all because of one failure - verify + clearPendingRequests(); + } + + void result( const LLSD& content ) + { + if ( !content.isMap() || content.has("error") ) + { + llwarns << "Error on fetched data"<< llendl; + //prep#do we really want to remove all because of one failure - verify + clearPendingRequests(); + return; + } + + //Differentiate what the incoming caps could be from the data + bool containsParcel = content.has("parcel"); + bool containsSelection = content.has("selected"); + + //Loop over the stored object ids checking against the incoming data + for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter ) + { + LLUUID objectID = iter->asUUID(); + + LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID ); + + if ( containsParcel ) + { + //Typically should be one + S32 dataCount = content["parcel"].size(); + for(S32 i = 0; i < dataCount; i++) + { + //prep#todo verify that this is safe, otherwise just add a bool + LLUUID parcelId; + //S32 parcelOwner = 0; + if ( content["parcel"][i].has("parcel_id") ) + { + parcelId = content["parcel"][i]["parcel_id"].asUUID(); + } + + //if ( content["parcel"][i].has("parcel_owner") ) + //{ + // parcelOwner = content["parcel"][i]["parcel_owner"].asInteger(); + //} + + F32 ownerRenderCost = 0; + F32 ownerPhysicsCost = 0; + F32 ownerNetworkCost = 0; + F32 ownerSimulationCost = 0; + + F32 groupRenderCost = 0; + F32 groupPhysicsCost = 0; + F32 groupNetworkCost = 0; + F32 groupSimulationCost = 0; + + F32 otherRenderCost = 0; + F32 otherPhysicsCost = 0; + F32 otherNetworkCost = 0; + F32 otherSimulationCost = 0; + + F32 tempRenderCost = 0; + F32 tempPhysicsCost = 0; + F32 tempNetworkCost = 0; + F32 tempSimulationCost = 0; + + F32 selectedRenderCost = 0; + F32 selectedPhysicsCost = 0; + F32 selectedNetworkCost = 0; + F32 selectedSimulationCost = 0; + + F32 parcelCapacity = 0; + + if ( content["parcel"][i].has("capacity") ) + { + parcelCapacity = content["parcel"][i].has("capacity"); + } + + if ( content["parcel"][i].has("owner") ) + { + ownerRenderCost = content["parcel"][i]["owner"]["rendering"].asReal(); + ownerPhysicsCost = content["parcel"][i]["owner"]["physics"].asReal(); + ownerNetworkCost = content["parcel"][i]["owner"]["streaming"].asReal(); + ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal(); + } + + if ( content["parcel"][i].has("group") ) + { + groupRenderCost = content["parcel"][i]["group"]["rendering"].asReal(); + groupPhysicsCost = content["parcel"][i]["group"]["physics"].asReal(); + groupNetworkCost = content["parcel"][i]["group"]["streaming"].asReal(); + groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal(); + + } + if ( content["parcel"][i].has("other") ) + { + otherRenderCost = content["parcel"][i]["other"]["rendering"].asReal(); + otherPhysicsCost = content["parcel"][i]["other"]["physics"].asReal(); + otherNetworkCost = content["parcel"][i]["other"]["streaming"].asReal(); + otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal(); + } + + if ( content["parcel"][i].has("temp") ) + { + tempRenderCost = content["parcel"][i]["total"]["rendering"].asReal(); + tempPhysicsCost = content["parcel"][i]["total"]["physics"].asReal(); + tempNetworkCost = content["parcel"][i]["total"]["streaming"].asReal(); + tempSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); + } + + if ( content["parcel"][i].has("selected") ) + { + selectedRenderCost = content["parcel"][i]["total"]["rendering"].asReal(); + selectedPhysicsCost = content["parcel"][i]["total"]["physics"].asReal(); + selectedNetworkCost = content["parcel"][i]["total"]["streaming"].asReal(); + selectedSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); + } + + ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost, + groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost, + otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost, + tempRenderCost, tempPhysicsCost, tempNetworkCost, tempSimulationCost, + selectedRenderCost, selectedPhysicsCost, selectedNetworkCost, selectedSimulationCost, + parcelCapacity ); + //Update the Parcel + LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); + if ( pParcel ) + { + pParcel->updateQuota( objectID, parcelQuota ); + } + } + } + else + if ( containsSelection ) + { + S32 dataCount = content["selected"].size(); + for(S32 i = 0; i < dataCount; i++) + { + + F32 renderCost = 0; + F32 physicsCost = 0; + F32 networkCost = 0; + F32 simulationCost = 0; + + LLUUID objectId; + + objectId = content["selected"][i]["local_id"].asUUID(); + renderCost = content["selected"][i]["rendering"].asReal(); + physicsCost = content["selected"][i]["physics"].asReal(); + networkCost = content["selected"][i]["streaming"].asReal(); + simulationCost = content["selected"][i]["simulation"].asReal(); + + SelectionQuota selectionQuota( objectId, renderCost, physicsCost, networkCost, simulationCost ); + + //Update the objects + gObjectList.updateQuota( objectId, selectionQuota ); + + } + } + else + { + //Nothing in string + LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID ); + } + } + } + +private: + //List of posted objects + LLSD mObjectIDs; +}; +//=============================================================================== +void LLAccountingQuotaManager::fetchQuotas( const std::string& url ) +{ + // Invoking system must have already determined capability availability + if ( !url.empty() ) + { + LLSD objectList; + U32 objectIndex = 0; + IDIt IDIter = mUpdateObjectQuota.begin(); + IDIt IDIterEnd = mUpdateObjectQuota.end(); + + for ( ; IDIter != IDIterEnd; ++IDIter ) + { + // Check to see if a request for this object has already been made. + if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() ) + { + mPendingObjectQuota.insert( *IDIter ); + objectList[objectIndex++] = *IDIter; + } + } + + mUpdateObjectQuota.clear(); + + //Post results + if ( objectList.size() > 0 ) + { + LLSD dataToPost = LLSD::emptyMap(); + dataToPost["object_ids"] = objectList; + LLHTTPClient::post( url, dataToPost, new LLAccountingQuotaResponder( objectList )); + } + } + else + { + //url was empty - warn & continue + llwarns<<"Supplied url is empty "<<llendl; + mUpdateObjectQuota.clear(); + mPendingObjectQuota.clear(); + } +} +//=============================================================================== +void LLAccountingQuotaManager::updateObjectCost( const LLUUID& objectID ) +{ + mUpdateObjectQuota.insert( objectID ); +} +//=============================================================================== +void LLAccountingQuotaManager::removePendingObjectQuota( const LLUUID& objectID ) +{ + mPendingObjectQuota.erase( objectID ); +} +//=============================================================================== diff --git a/indra/newview/llaccountingquotamanager.h b/indra/newview/llaccountingquotamanager.h new file mode 100644 index 0000000000..9251ef9351 --- /dev/null +++ b/indra/newview/llaccountingquotamanager.h @@ -0,0 +1,55 @@ +/** + * @file lllAccountingQuotaManager.h + * @ + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_ACCOUNTINGQUOTAMANAGER_H +#define LL_ACCOUNTINGQUOTAMANAGER_H +//=============================================================================== +#include "llaccountingquota.h" +//=============================================================================== +class LLAccountingQuotaManager : public LLSingleton<LLAccountingQuotaManager> +{ +public: + //Ctor + LLAccountingQuotaManager(); + //Store an object that will be eventually fetched + void updateObjectCost( const LLUUID& objectID ); + //Request quotas for object list + void fetchQuotas( const std::string& url ); + //Delete a specific object from the pending list + void removePendingObjectQuota( const LLUUID& objectID ); + +private: + //Set of objects that need to update their cost + std::set<LLUUID> mUpdateObjectQuota; + //During fetchQuota we move object into a the pending set to signify that + //a fetch has been instigated. + std::set<LLUUID> mPendingObjectQuota; + typedef std::set<LLUUID>::iterator IDIt; +}; +//=============================================================================== + +#endif // LLACCOUNTINGQUOTAMANAGER + diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 08d71fc8fc..446ded8096 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -206,6 +206,7 @@ LLAgent::LLAgent() : mAutoPilot(FALSE), mAutoPilotFlyOnStop(FALSE), + mAutoPilotAllowFlying(TRUE), mAutoPilotTargetGlobal(), mAutoPilotStopDistance(1.f), mAutoPilotUseRotation(FALSE), @@ -1230,17 +1231,26 @@ void LLAgent::startAutoPilotGlobal( const LLQuaternion *target_rotation, void (*finish_callback)(BOOL, void *), void *callback_data, - F32 stop_distance, F32 rot_threshold) + F32 stop_distance, + F32 rot_threshold, + BOOL allow_flying) { if (!isAgentAvatarValid()) { return; } + // Are there any pending callbacks from previous auto pilot requests? + if (mAutoPilotFinishedCallback) + { + mAutoPilotFinishedCallback(dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData); + } + mAutoPilotFinishedCallback = finish_callback; mAutoPilotCallbackData = callback_data; mAutoPilotRotationThreshold = rot_threshold; mAutoPilotBehaviorName = behavior_name; + mAutoPilotAllowFlying = allow_flying; LLVector3d delta_pos( target_global ); delta_pos -= getPositionGlobal(); @@ -1268,14 +1278,23 @@ void LLAgent::startAutoPilotGlobal( } } - mAutoPilotFlyOnStop = getFlying(); + if (mAutoPilotAllowFlying) + { + mAutoPilotFlyOnStop = getFlying(); + } + else + { + mAutoPilotFlyOnStop = FALSE; + } - if (distance > 30.0) + if (distance > 30.0 && mAutoPilotAllowFlying) { setFlying(TRUE); } - if ( distance > 1.f && heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f)) + if ( distance > 1.f && + mAutoPilotAllowFlying && + heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f)) { setFlying(TRUE); // Do not force flying for "Sit" behavior to prevent flying after pressing "Stand" @@ -1285,22 +1304,8 @@ void LLAgent::startAutoPilotGlobal( } mAutoPilot = TRUE; - mAutoPilotTargetGlobal = target_global; - - // trace ray down to find height of destination from ground - LLVector3d traceEndPt = target_global; - traceEndPt.mdV[VZ] -= 20.f; + setAutoPilotTargetGlobal(target_global); - LLVector3d targetOnGround; - LLVector3 groundNorm; - LLViewerObject *obj; - - LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); - F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); - - // clamp z value of target to minimum height above ground - mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height; - mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal); if (target_rotation) { mAutoPilotUseRotation = TRUE; @@ -1318,12 +1323,36 @@ void LLAgent::startAutoPilotGlobal( //----------------------------------------------------------------------------- -// startFollowPilot() +// setAutoPilotTargetGlobal //----------------------------------------------------------------------------- -void LLAgent::startFollowPilot(const LLUUID &leader_id) +void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global) { - if (!mAutoPilot) return; + if (mAutoPilot) + { + mAutoPilotTargetGlobal = target_global; + + // trace ray down to find height of destination from ground + LLVector3d traceEndPt = target_global; + traceEndPt.mdV[VZ] -= 20.f; + + LLVector3d targetOnGround; + LLVector3 groundNorm; + LLViewerObject *obj; + + LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); + F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); + + // clamp z value of target to minimum height above ground + mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height; + mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal); + } +} +//----------------------------------------------------------------------------- +// startFollowPilot() +//----------------------------------------------------------------------------- +void LLAgent::startFollowPilot(const LLUUID &leader_id, BOOL allow_flying, F32 stop_distance) +{ mLeaderID = leader_id; if ( mLeaderID.isNull() ) return; @@ -1334,7 +1363,14 @@ void LLAgent::startFollowPilot(const LLUUID &leader_id) return; } - startAutoPilotGlobal(object->getPositionGlobal()); + startAutoPilotGlobal(object->getPositionGlobal(), + std::string(), // behavior_name + NULL, // target_rotation + NULL, // finish_callback + NULL, // callback_data + stop_distance, + 0.03f, // rotation_threshold + allow_flying); } @@ -1360,7 +1396,8 @@ void LLAgent::stopAutoPilot(BOOL user_cancel) //NB: auto pilot can terminate for a reason other than reaching the destination if (mAutoPilotFinishedCallback) { - mAutoPilotFinishedCallback(!user_cancel && dist_vec_squared(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < (mAutoPilotStopDistance * mAutoPilotStopDistance), mAutoPilotCallbackData); + mAutoPilotFinishedCallback(!user_cancel && dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData); + mAutoPilotFinishedCallback = NULL; } mLeaderID = LLUUID::null; @@ -1400,7 +1437,7 @@ void LLAgent::autoPilot(F32 *delta_yaw) if (!isAgentAvatarValid()) return; - if (gAgentAvatarp->mInAir) + if (gAgentAvatarp->mInAir && mAutoPilotAllowFlying) { setFlying(TRUE); } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 54c5649f97..67ed1923c0 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -469,19 +469,29 @@ public: public: BOOL getAutoPilot() const { return mAutoPilot; } LLVector3d getAutoPilotTargetGlobal() const { return mAutoPilotTargetGlobal; } + LLUUID getAutoPilotLeaderID() const { return mLeaderID; } + F32 getAutoPilotStopDistance() const { return mAutoPilotStopDistance; } + F32 getAutoPilotTargetDist() const { return mAutoPilotTargetDist; } + BOOL getAutoPilotUseRotation() const { return mAutoPilotUseRotation; } + LLVector3 getAutoPilotTargetFacing() const { return mAutoPilotTargetFacing; } + F32 getAutoPilotRotationThreshold() const { return mAutoPilotRotationThreshold; } + std::string getAutoPilotBehaviorName() const { return mAutoPilotBehaviorName; } + void startAutoPilotGlobal(const LLVector3d &pos_global, const std::string& behavior_name = std::string(), const LLQuaternion *target_rotation = NULL, void (*finish_callback)(BOOL, void *) = NULL, void *callback_data = NULL, - F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f); - void startFollowPilot(const LLUUID &leader_id); + F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f, + BOOL allow_flying = TRUE); + void startFollowPilot(const LLUUID &leader_id, BOOL allow_flying = TRUE, F32 stop_distance = 0.5f); void stopAutoPilot(BOOL user_cancel = FALSE); - void setAutoPilotGlobal(const LLVector3d &pos_global); + void setAutoPilotTargetGlobal(const LLVector3d &target_global); void autoPilot(F32 *delta_yaw); // Autopilot walking action, angles in radians void renderAutoPilotTarget(); private: BOOL mAutoPilot; BOOL mAutoPilotFlyOnStop; + BOOL mAutoPilotAllowFlying; LLVector3d mAutoPilotTargetGlobal; F32 mAutoPilotStopDistance; BOOL mAutoPilotUseRotation; diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index c6b5a0113f..c30d3b9aa3 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -392,7 +392,7 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi } LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation - LLVector3 object_extents; + LLVector3 object_extents = object->getScale(); const LLVector4a* oe4 = object->mDrawable->getSpatialExtents(); object_extents.set( oe4[1][0], oe4[1][1], oe4[1][2] ); diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 9cea33c7c6..a8d2222c03 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -31,6 +31,7 @@ #include "llagentlistener.h" #include "llagent.h" +#include "llvoavatar.h" #include "llcommandhandler.h" #include "llslurl.h" #include "llurldispatcher.h" @@ -39,93 +40,242 @@ #include "llviewerregion.h" #include "llsdutil.h" #include "llsdutil_math.h" +#include "lltoolgrab.h" +#include "llhudeffectlookat.h" +#include "llagentcamera.h" LLAgentListener::LLAgentListener(LLAgent &agent) : LLEventAPI("LLAgent", "LLAgent listener to (e.g.) teleport, sit, stand, etc."), mAgent(agent) { - add("requestTeleport", + add("requestTeleport", "Teleport: [\"regionname\"], [\"x\"], [\"y\"], [\"z\"]\n" "If [\"skip_confirmation\"] is true, use LLURLDispatcher rather than LLCommandDispatcher.", &LLAgentListener::requestTeleport); - add("requestSit", - "Ask to sit on the object specified in [\"obj_uuid\"]", + add("requestSit", + "[\"obj_uuid\"]: id of object to sit on, use this or [\"position\"] to indicate the sit target" + "[\"position\"]: region position {x, y, z} where to find closest object to sit on", &LLAgentListener::requestSit); - add("requestStand", + add("requestStand", "Ask to stand up", &LLAgentListener::requestStand); + add("requestTouch", + "[\"obj_uuid\"]: id of object to touch, use this or [\"position\"] to indicate the object to touch" + "[\"position\"]: region position {x, y, z} where to find closest object to touch" + "[\"face\"]: optional object face number to touch[Default: 0]", + &LLAgentListener::requestTouch); add("resetAxes", "Set the agent to a fixed orientation (optionally specify [\"lookat\"] = array of [x, y, z])", &LLAgentListener::resetAxes); add("getAxes", + "Obsolete - use getPosition instead\n" "Send information about the agent's orientation on [\"reply\"]:\n" "[\"euler\"]: map of {roll, pitch, yaw}\n" "[\"quat\"]: array of [x, y, z, w] quaternion values", &LLAgentListener::getAxes, LLSDMap("reply", LLSD())); - add("getGroups", - "Send on [\"reply\"], in [\"groups\"], an array describing agent's groups:\n" - "[\"id\"]: UUID of group\n" - "[\"name\"]: name of group", - &LLAgentListener::getGroups, + add("getPosition", + "Send information about the agent's position and orientation on [\"reply\"]:\n" + "[\"region\"]: array of region {x, y, z} position\n" + "[\"global\"]: array of global {x, y, z} position\n" + "[\"euler\"]: map of {roll, pitch, yaw}\n" + "[\"quat\"]: array of [x, y, z, w] quaternion values", + &LLAgentListener::getPosition, LLSDMap("reply", LLSD())); + add("startAutoPilot", + "Start the autopilot system using the following parameters:\n" + "[\"target_global\"]: array of target global {x, y, z} position\n" + "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]\n" + "[\"target_rotation\"]: array of [x, y, z, w] quaternion values [default: no target]\n" + "[\"rotation_threshold\"]: target maximum angle from target facing rotation [default: 0.03 radians]\n" + "[\"behavior_name\"]: name of the autopilot behavior [default: \"\"]" + "[\"allow_flying\"]: allow flying during autopilot [default: True]", + //"[\"callback_pump\"]: pump to send success/failure and callback data to [default: none]\n" + //"[\"callback_data\"]: data to send back during a callback [default: none]", + &LLAgentListener::startAutoPilot); + add("getAutoPilot", + "Send information about current state of the autopilot system to [\"reply\"]:\n" + "[\"enabled\"]: boolean indicating whether or not autopilot is enabled\n" + "[\"target_global\"]: array of target global {x, y, z} position\n" + "[\"leader_id\"]: uuid of target autopilot is following\n" + "[\"stop_distance\"]: target maximum distance from target\n" + "[\"target_distance\"]: last known distance from target\n" + "[\"use_rotation\"]: boolean indicating if autopilot has a target facing rotation\n" + "[\"target_facing\"]: array of {x, y} target direction to face\n" + "[\"rotation_threshold\"]: target maximum angle from target facing rotation\n" + "[\"behavior_name\"]: name of the autopilot behavior", + &LLAgentListener::getAutoPilot, + LLSDMap("reply", LLSD())); + add("startFollowPilot", + "[\"leader_id\"]: uuid of target to follow using the autopilot system (optional with avatar_name)\n" + "[\"avatar_name\"]: avatar name to follow using the autopilot system (optional with leader_id)\n" + "[\"allow_flying\"]: allow flying during autopilot [default: True]\n" + "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]", + &LLAgentListener::startFollowPilot); + add("setAutoPilotTarget", + "Update target for currently running autopilot:\n" + "[\"target_global\"]: array of target global {x, y, z} position", + &LLAgentListener::setAutoPilotTarget); + add("stopAutoPilot", + "Stop the autopilot system:\n" + "[\"user_cancel\"] indicates whether or not to act as though user canceled autopilot [default: false]", + &LLAgentListener::stopAutoPilot); + add("lookAt", + "[\"type\"]: number to indicate the lookAt type, 0 to clear\n" + "[\"obj_uuid\"]: id of object to look at, use this or [\"position\"] to indicate the target\n" + "[\"position\"]: region position {x, y, z} where to find closest object or avatar to look at", + &LLAgentListener::lookAt); } void LLAgentListener::requestTeleport(LLSD const & event_data) const { - if(event_data["skip_confirmation"].asBoolean()) + if(event_data["skip_confirmation"].asBoolean()) + { + LLSD params(LLSD::emptyArray()); + params.append(event_data["regionname"]); + params.append(event_data["x"]); + params.append(event_data["y"]); + params.append(event_data["z"]); + LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, "clicked", true); + // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat" + // should we just compose LLCommandHandler and LLDispatchListener? + } + else + { + std::string url = LLSLURL(event_data["regionname"], + LLVector3(event_data["x"].asReal(), + event_data["y"].asReal(), + event_data["z"].asReal())).getSLURLString(); + LLURLDispatcher::dispatch(url, "clicked", NULL, false); + } +} + +void LLAgentListener::requestSit(LLSD const & event_data) const +{ + //mAgent.getAvatarObject()->sitOnObject(); + // shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand() + // *TODO - find a permanent place to share this code properly. + + LLViewerObject *object = NULL; + if (event_data.has("obj_uuid")) + { + object = gObjectList.findObject(event_data["obj_uuid"]); + } + else if (event_data.has("position")) { - LLSD params(LLSD::emptyArray()); - params.append(event_data["regionname"]); - params.append(event_data["x"]); - params.append(event_data["y"]); - params.append(event_data["z"]); - LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, "clicked", true); - // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat" - // should we just compose LLCommandHandler and LLDispatchListener? + LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); + object = findObjectClosestTo(target_position); } + + if (object && object->getPCode() == LL_PCODE_VOLUME) + { + gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, mAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, mAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_TargetObject); + gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); + gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3(0,0,0)); + + object->getRegion()->sendReliableMessage(); + } else { - std::string url = LLSLURL(event_data["regionname"], - LLVector3(event_data["x"].asReal(), - event_data["y"].asReal(), - event_data["z"].asReal())).getSLURLString(); - LLURLDispatcher::dispatch(url, "clicked", NULL, false); + llwarns << "LLAgent requestSit could not find the sit target: " + << event_data << llendl; } } -void LLAgentListener::requestSit(LLSD const & event_data) const +void LLAgentListener::requestStand(LLSD const & event_data) const +{ + mAgent.setControlFlags(AGENT_CONTROL_STAND_UP); +} + + +LLViewerObject * LLAgentListener::findObjectClosestTo( const LLVector3 & position ) const { - //mAgent.getAvatarObject()->sitOnObject(); - // shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand() - // *TODO - find a permanent place to share this code properly. - LLViewerObject *object = gObjectList.findObject(event_data["obj_uuid"]); + LLViewerObject *object = NULL; - if (object && object->getPCode() == LL_PCODE_VOLUME) + // Find the object closest to that position + F32 min_distance = 10000.0f; // Start big + S32 num_objects = gObjectList.getNumObjects(); + S32 cur_index = 0; + while (cur_index < num_objects) { - gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, mAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, mAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_TargetObject); - gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); - gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3(0,0,0)); - - object->getRegion()->sendReliableMessage(); + LLViewerObject * cur_object = gObjectList.getObject(cur_index++); + if (cur_object) + { // Calculate distance from the target position + LLVector3 target_diff = cur_object->getPositionRegion() - position; + F32 distance_to_target = target_diff.length(); + if (distance_to_target < min_distance) + { // Found an object closer + min_distance = distance_to_target; + object = cur_object; + } + } } + + return object; } -void LLAgentListener::requestStand(LLSD const & event_data) const + +void LLAgentListener::requestTouch(LLSD const & event_data) const { - mAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + LLViewerObject *object = NULL; + + if (event_data.has("obj_uuid")) + { + object = gObjectList.findObject(event_data["obj_uuid"]); + } + else if (event_data.has("position")) + { + LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); + object = findObjectClosestTo(target_position); + } + + S32 face = 0; + if (event_data.has("face")) + { + face = event_data["face"].asInteger(); + } + + if (object && object->getPCode() == LL_PCODE_VOLUME) + { + // Fake enough pick info to get it to (hopefully) work + LLPickInfo pick; + pick.mObjectFace = face; + + /* + These values are sent to the simulator, but face seems to be easiest to use + + pick.mUVCoords "UVCoord" + pick.mSTCoords "STCoord" + pick.mObjectFace "FaceIndex" + pick.mIntersection "Position" + pick.mNormal "Normal" + pick.mBinormal "Binormal" + */ + + // A touch is a sketchy message sequence ... send a grab, immediately + // followed by un-grabbing, crossing fingers and hoping packets arrive in + // the correct order + send_ObjectGrab_message(object, pick, LLVector3::zero); + send_ObjectDeGrab_message(object, pick); + } + else + { + llwarns << "LLAgent requestTouch could not find the touch target " + << event_data["obj_uuid"].asUUID() << llendl; + } } -void LLAgentListener::resetAxes(const LLSD& event) const + +void LLAgentListener::resetAxes(const LLSD& event_data) const { - if (event.has("lookat")) + if (event_data.has("lookat")) { - mAgent.resetAxes(ll_vector3_from_sd(event["lookat"])); + mAgent.resetAxes(ll_vector3_from_sd(event_data["lookat"])); } else { @@ -134,17 +284,210 @@ void LLAgentListener::resetAxes(const LLSD& event) const } } -void LLAgentListener::getAxes(const LLSD& event) const +void LLAgentListener::getAxes(const LLSD& event_data) const { LLQuaternion quat(mAgent.getQuat()); F32 roll, pitch, yaw; quat.getEulerAngles(&roll, &pitch, &yaw); // The official query API for LLQuaternion's [x, y, z, w] values is its // public member mQ... - sendReply(LLSDMap - ("quat", llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ))) - ("euler", LLSDMap("roll", roll)("pitch", pitch)("yaw", yaw)), - event); + LLSD reply = LLSD::emptyMap(); + reply["quat"] = llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ)); + reply["euler"] = LLSD::emptyMap(); + reply["euler"]["roll"] = roll; + reply["euler"]["pitch"] = pitch; + reply["euler"]["yaw"] = yaw; + sendReply(reply, event_data); +} + +void LLAgentListener::getPosition(const LLSD& event_data) const +{ + F32 roll, pitch, yaw; + LLQuaternion quat(mAgent.getQuat()); + quat.getEulerAngles(&roll, &pitch, &yaw); + + LLSD reply = LLSD::emptyMap(); + reply["quat"] = llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ)); + reply["euler"] = LLSD::emptyMap(); + reply["euler"]["roll"] = roll; + reply["euler"]["pitch"] = pitch; + reply["euler"]["yaw"] = yaw; + reply["region"] = ll_sd_from_vector3(mAgent.getPositionAgent()); + reply["global"] = ll_sd_from_vector3d(mAgent.getPositionGlobal()); + + sendReply(reply, event_data); +} + + +void LLAgentListener::startAutoPilot(LLSD const & event_data) +{ + LLQuaternion target_rotation_value; + LLQuaternion* target_rotation = NULL; + if (event_data.has("target_rotation")) + { + target_rotation_value = ll_quaternion_from_sd(event_data["target_rotation"]); + target_rotation = &target_rotation_value; + } + // *TODO: Use callback_pump and callback_data + F32 rotation_threshold = 0.03f; + if (event_data.has("rotation_threshold")) + { + rotation_threshold = event_data["rotation_threshold"].asReal(); + } + + BOOL allow_flying = TRUE; + if (event_data.has("allow_flying")) + { + allow_flying = (BOOL) event_data["allow_flying"].asBoolean(); + mAgent.setFlying(allow_flying); + } + + F32 stop_distance = 0.f; + if (event_data.has("stop_distance")) + { + stop_distance = event_data["stop_distance"].asReal(); + } + + // Clear follow target, this is doing a path + mFollowTarget.setNull(); + + mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event_data["target_global"]), + event_data["behavior_name"], + target_rotation, + NULL, NULL, + stop_distance, + rotation_threshold, + allow_flying); +} + +void LLAgentListener::getAutoPilot(const LLSD& event_data) const +{ + LLSD reply = LLSD::emptyMap(); + + LLSD::Boolean enabled = mAgent.getAutoPilot(); + reply["enabled"] = enabled; + + reply["target_global"] = ll_sd_from_vector3d(mAgent.getAutoPilotTargetGlobal()); + + reply["leader_id"] = mAgent.getAutoPilotLeaderID(); + + reply["stop_distance"] = mAgent.getAutoPilotStopDistance(); + + reply["target_distance"] = mAgent.getAutoPilotTargetDist(); + if (!enabled && + mFollowTarget.notNull()) + { // Get an actual distance from the target object we were following + LLViewerObject * target = gObjectList.findObject(mFollowTarget); + if (target) + { // Found the target AV, return the actual distance to them as well as their ID + LLVector3 difference = target->getPositionRegion() - mAgent.getPositionAgent(); + reply["target_distance"] = difference.length(); + reply["leader_id"] = mFollowTarget; + } + } + + reply["use_rotation"] = (LLSD::Boolean) mAgent.getAutoPilotUseRotation(); + reply["target_facing"] = ll_sd_from_vector3(mAgent.getAutoPilotTargetFacing()); + reply["rotation_threshold"] = mAgent.getAutoPilotRotationThreshold(); + reply["behavior_name"] = mAgent.getAutoPilotBehaviorName(); + reply["fly"] = (LLSD::Boolean) mAgent.getFlying(); + + sendReply(reply, event_data); +} + +void LLAgentListener::startFollowPilot(LLSD const & event_data) +{ + LLUUID target_id; + + BOOL allow_flying = TRUE; + if (event_data.has("allow_flying")) + { + allow_flying = (BOOL) event_data["allow_flying"].asBoolean(); + } + + if (event_data.has("leader_id")) + { + target_id = event_data["leader_id"]; + } + else if (event_data.has("avatar_name")) + { // Find the avatar with matching name + std::string target_name = event_data["avatar_name"].asString(); + + if (target_name.length() > 0) + { + S32 num_objects = gObjectList.getNumObjects(); + S32 cur_index = 0; + while (cur_index < num_objects) + { + LLViewerObject * cur_object = gObjectList.getObject(cur_index++); + if (cur_object && + cur_object->asAvatar() && + cur_object->asAvatar()->getFullname() == target_name) + { // Found avatar with matching name, extract id and break out of loop + target_id = cur_object->getID(); + break; + } + } + } + } + + F32 stop_distance = 0.f; + if (event_data.has("stop_distance")) + { + stop_distance = event_data["stop_distance"].asReal(); + } + + if (target_id.notNull()) + { + mAgent.setFlying(allow_flying); + mFollowTarget = target_id; // Save follow target so we can report distance later + + mAgent.startFollowPilot(target_id, allow_flying, stop_distance); + } +} + +void LLAgentListener::setAutoPilotTarget(LLSD const & event_data) const +{ + if (event_data.has("target_global")) + { + LLVector3d target_global(ll_vector3d_from_sd(event_data["target_global"])); + mAgent.setAutoPilotTargetGlobal(target_global); + } +} + +void LLAgentListener::stopAutoPilot(LLSD const & event_data) const +{ + BOOL user_cancel = FALSE; + if (event_data.has("user_cancel")) + { + user_cancel = event_data["user_cancel"].asBoolean(); + } + mAgent.stopAutoPilot(user_cancel); +} + +void LLAgentListener::lookAt(LLSD const & event_data) const +{ + LLViewerObject *object = NULL; + if (event_data.has("obj_uuid")) + { + object = gObjectList.findObject(event_data["obj_uuid"]); + } + else if (event_data.has("position")) + { + LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); + object = findObjectClosestTo(target_position); + } + + S32 look_at_type = (S32) LOOKAT_TARGET_NONE; + if (event_data.has("type")) + { + look_at_type = event_data["type"].asInteger(); + } + if (look_at_type >= (S32) LOOKAT_TARGET_NONE && + look_at_type < (S32) LOOKAT_NUM_TARGETS) + { + gAgentCamera.setLookAt((ELookAtType) look_at_type, object); + } } void LLAgentListener::getGroups(const LLSD& event) const diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index 5a89a99f6a..9a9c4073fe 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -34,22 +34,35 @@ class LLAgent; class LLSD; +class LLViewerObject; +class LLVector3d; class LLAgentListener : public LLEventAPI { public: - LLAgentListener(LLAgent &agent); + LLAgentListener(LLAgent &agent); private: - void requestTeleport(LLSD const & event_data) const; - void requestSit(LLSD const & event_data) const; - void requestStand(LLSD const & event_data) const; - void resetAxes(const LLSD& event) const; - void getAxes(const LLSD& event) const; + void requestTeleport(LLSD const & event_data) const; + void requestSit(LLSD const & event_data) const; + void requestStand(LLSD const & event_data) const; + void requestTouch(LLSD const & event_data) const; + void resetAxes(const LLSD& event_data) const; + void getAxes(const LLSD& event_data) const; void getGroups(const LLSD& event) const; + void getPosition(const LLSD& event_data) const; + void startAutoPilot(const LLSD& event_data); + void getAutoPilot(const LLSD& event_data) const; + void startFollowPilot(const LLSD& event_data); + void setAutoPilotTarget(const LLSD& event_data) const; + void stopAutoPilot(const LLSD& event_data) const; + void lookAt(LLSD const & event_data) const; + + LLViewerObject * findObjectClosestTo( const LLVector3 & position ) const; private: - LLAgent & mAgent; + LLAgent & mAgent; + LLUUID mFollowTarget; }; #endif // LL_LLAGENTLISTENER_H diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 75b6c18c57..d2582d524d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -695,6 +695,8 @@ bool LLAppViewer::init() if (!initConfiguration()) return false; + LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ; + // write Google Breakpad minidump files to our log directory std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); logdir += gDirUtilp->getDirDelimiter(); @@ -721,6 +723,8 @@ bool LLAppViewer::init() // *NOTE:Mani - LLCurl::initClass is not thread safe. // Called before threads are created. LLCurl::initClass(); + LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ; + LLMachineID::init(); { @@ -739,6 +743,8 @@ bool LLAppViewer::init() } initThreads(); + LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ; + writeSystemInfo(); // Initialize updater service (now that we have an io pump) @@ -773,6 +779,7 @@ bool LLAppViewer::init() gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ALWAYS_SEND); gCrashSettings.saveToFile(crash_settings_filename, FALSE); } + LL_INFOS("InitInfo") << "Crash settings done." << LL_ENDL ; ///////////////////////////////////////////////// // OS-specific login dialogs @@ -821,6 +828,8 @@ bool LLAppViewer::init() // Let code in llui access the viewer help floater LLUI::sHelpImpl = LLViewerHelp::getInstance(); + LL_INFOS("InitInfo") << "UI initialization is done." << LL_ENDL ; + // Load translations for tooltips LLFloater::initClass(); @@ -870,6 +879,7 @@ bool LLAppViewer::init() // Early out from user choice. return false; } + LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ; // Prepare for out-of-memory situations, during which we will crash on // purpose and save a dump. @@ -890,7 +900,8 @@ bool LLAppViewer::init() OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK); return 1; } - + LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ; + // Initialize the repeater service. LLMainLoopRepeater::instance().start(); @@ -899,6 +910,7 @@ bool LLAppViewer::init() // gGLActive = TRUE; initWindow(); + LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ; // initWindow also initializes the Feature List, so now we can initialize this global. LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); @@ -1036,6 +1048,8 @@ bool LLAppViewer::init() } LLViewerMedia::initClass(); + LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ; + LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match; //EXT-7013 - On windows for some locale (Japanese) standard @@ -1179,11 +1193,11 @@ bool LLAppViewer::mainLoop() // Scan keyboard for movement keys. Command keys and typing // are handled by windows callbacks. Don't do this until we're // done initializing. JC - if (gViewerWindow->mWindow->getVisible() + if ((gHeadlessClient || gViewerWindow->mWindow->getVisible()) && gViewerWindow->getActive() && !gViewerWindow->mWindow->getMinimized() && LLStartUp::getStartupState() == STATE_STARTED - && !gViewerWindow->getShowProgress() + && (gHeadlessClient || !gViewerWindow->getShowProgress()) && !gFocusMgr.focusLocked()) { LLMemType mjk(LLMemType::MTYPE_JOY_KEY); @@ -2502,7 +2516,8 @@ bool LLAppViewer::initConfiguration() // it relies on checking a marker file which will not work when running // out of different directories - if (LLStartUp::getStartSLURL().isValid()) + if (LLStartUp::getStartSLURL().isValid() && + (gSavedSettings.getBOOL("SLURLPassToOtherInstance"))) { if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString())) { @@ -2812,6 +2827,8 @@ bool LLAppViewer::initWindow() gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"), gSavedSettings.getBOOL("WindowFullScreen"), ignorePixelDepth); + LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL; + // Need to load feature table before cheking to start watchdog. const S32 NEVER_SUBMIT_REPORT = 2; bool use_watchdog = false; @@ -2831,6 +2848,7 @@ bool LLAppViewer::initWindow() { LLWatchdog::getInstance()->init(watchdog_killer_callback); } + LL_INFOS("AppInit") << "watchdog setting is done." << LL_ENDL; LLNotificationsUI::LLNotificationManager::getInstance(); @@ -2853,7 +2871,8 @@ bool LLAppViewer::initWindow() gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); gPipeline.init(); - + LL_INFOS("AppInit") << "gPipeline Initialized" << LL_ENDL; + stop_glerror(); gViewerWindow->initGLDefaults(); @@ -2892,7 +2911,7 @@ bool LLAppViewer::initWindow() // show viewer window //gViewerWindow->mWindow->show(); - + LL_INFOS("AppInit") << "Window initialization done." << LL_ENDL; return true; } @@ -3478,7 +3497,7 @@ void LLAppViewer::migrateCacheDirectory() // Migrate inventory cache to avoid pain to inventory database after mass update S32 file_count = 0; std::string file_name; - std::string mask = delimiter + "*.*"; + std::string mask = "*.*"; LLDirIterator iter(old_cache_dir, mask); while (iter.next(file_name)) @@ -3634,11 +3653,25 @@ bool LLAppViewer::initCache() // Init the texture cache // Allocate 80% of the cache size for textures - const S32 MB = 1024*1024; + const S32 MB = 1024 * 1024; + const S64 MIN_CACHE_SIZE = 64 * MB; + const S64 MAX_CACHE_SIZE = 9984ll * MB; + const S64 MAX_VFS_SIZE = 1024 * MB; // 1 GB + S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB; - const S64 MAX_CACHE_SIZE = 1024*MB; - cache_size = llmin(cache_size, MAX_CACHE_SIZE); - S64 texture_cache_size = ((cache_size * 8)/10); + cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); + + S64 texture_cache_size = ((cache_size * 8) / 10); + S64 vfs_size = cache_size - texture_cache_size; + + if (vfs_size > MAX_VFS_SIZE) + { + // Give the texture cache more space, since the VFS can't be bigger than 1GB. + // This happens when the user's CacheSize setting is greater than 5GB. + vfs_size = MAX_VFS_SIZE; + texture_cache_size = cache_size - MAX_VFS_SIZE; + } + S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); texture_cache_size -= extra; @@ -3647,21 +3680,19 @@ bool LLAppViewer::initCache() LLSplashScreen::update(LLTrans::getString("StartupInitializingVFS")); // Init the VFS - S64 vfs_size = cache_size - texture_cache_size; - const S64 MAX_VFS_SIZE = 1024 * MB; // 1 GB - vfs_size = llmin(vfs_size, MAX_VFS_SIZE); + vfs_size = llmin(vfs_size + extra, MAX_VFS_SIZE); vfs_size = (vfs_size / MB) * MB; // make sure it is MB aligned U32 vfs_size_u32 = (U32)vfs_size; U32 old_vfs_size = gSavedSettings.getU32("VFSOldSize") * MB; bool resize_vfs = (vfs_size_u32 != old_vfs_size); if (resize_vfs) { - gSavedSettings.setU32("VFSOldSize", vfs_size_u32/MB); + gSavedSettings.setU32("VFSOldSize", vfs_size_u32 / MB); } - LL_INFOS("AppCache") << "VFS CACHE SIZE: " << vfs_size/(1024*1024) << " MB" << LL_ENDL; + LL_INFOS("AppCache") << "VFS CACHE SIZE: " << vfs_size / (1024*1024) << " MB" << LL_ENDL; // This has to happen BEFORE starting the vfs - //time_t ltime; + // time_t ltime; srand(time(NULL)); // Flawfinder: ignore U32 old_salt = gSavedSettings.getU32("VFSSalt"); U32 new_salt; @@ -3682,10 +3713,10 @@ bool LLAppViewer::initCache() do { new_salt = rand(); - } while( new_salt == old_salt ); + } while(new_salt == old_salt); } - old_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE) + llformat("%u",old_salt); + old_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_DATA_FILE_BASE) + llformat("%u", old_salt); // make sure this file exists llstat s; @@ -3694,12 +3725,11 @@ bool LLAppViewer::initCache() { // doesn't exist, look for a data file std::string mask; - mask = gDirUtilp->getDirDelimiter(); - mask += VFS_DATA_FILE_BASE; + mask = VFS_DATA_FILE_BASE; mask += "*"; std::string dir; - dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""); + dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""); std::string found_file; LLDirIterator iter(dir, mask); @@ -3716,7 +3746,7 @@ bool LLAppViewer::initCache() } } - old_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_INDEX_FILE_BASE) + llformat("%u",old_salt); + old_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE) + llformat("%u", old_salt); stat_result = LLFile::stat(old_vfs_index_file, &s); if (stat_result) @@ -3729,27 +3759,25 @@ bool LLAppViewer::initCache() // Just in case, nuke any other old cache files in the directory. std::string dir; - dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""); + dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""); std::string mask; - mask = gDirUtilp->getDirDelimiter(); - mask += VFS_DATA_FILE_BASE; + mask = VFS_DATA_FILE_BASE; mask += "*"; gDirUtilp->deleteFilesInDir(dir, mask); - mask = gDirUtilp->getDirDelimiter(); - mask += VFS_INDEX_FILE_BASE; + mask = VFS_INDEX_FILE_BASE; mask += "*"; gDirUtilp->deleteFilesInDir(dir, mask); } - new_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE) + llformat("%u",new_salt); - new_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE) + llformat("%u",new_salt); + new_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_DATA_FILE_BASE) + llformat("%u", new_salt); + new_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE) + llformat("%u", new_salt); - static_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_data.db2"); - static_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_index.db2"); + static_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "static_data.db2"); + static_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "static_index.db2"); if (resize_vfs) { @@ -3772,19 +3800,19 @@ bool LLAppViewer::initCache() // Don't remove VFS after viewer crashes. If user has corrupt data, they can reinstall. JC gVFS = LLVFS::createLLVFS(new_vfs_index_file, new_vfs_data_file, false, vfs_size_u32, false); - if( !gVFS ) + if (!gVFS) { return false; } gStaticVFS = LLVFS::createLLVFS(static_vfs_index_file, static_vfs_data_file, true, 0, false); - if( !gStaticVFS ) + if (!gStaticVFS) { return false; } BOOL success = gVFS->isValid() && gStaticVFS->isValid(); - if( !success ) + if (!success) { return false; } @@ -3805,11 +3833,11 @@ bool LLAppViewer::initCache() void LLAppViewer::purgeCache() { - LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << llendl; + LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL; LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE); LLVOCache::getInstance()->removeCache(LL_PATH_CACHE); - std::string mask = gDirUtilp->getDirDelimiter() + "*.*"; - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask); + std::string mask = "*.*"; + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask); } std::string LLAppViewer::getSecondLifeTitle() const diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 6396ca91ff..445bd208ef 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -295,23 +295,44 @@ void create_console() // redirect unbuffered STDOUT to the console l_std_handle = (long)GetStdHandle(STD_OUTPUT_HANDLE); h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); - fp = _fdopen( h_con_handle, "w" ); - *stdout = *fp; - setvbuf( stdout, NULL, _IONBF, 0 ); + if (h_con_handle == -1) + { + llwarns << "create_console() failed to open stdout handle" << llendl; + } + else + { + fp = _fdopen( h_con_handle, "w" ); + *stdout = *fp; + setvbuf( stdout, NULL, _IONBF, 0 ); + } // redirect unbuffered STDIN to the console l_std_handle = (long)GetStdHandle(STD_INPUT_HANDLE); h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); - fp = _fdopen( h_con_handle, "r" ); - *stdin = *fp; - setvbuf( stdin, NULL, _IONBF, 0 ); + if (h_con_handle == -1) + { + llwarns << "create_console() failed to open stdin handle" << llendl; + } + else + { + fp = _fdopen( h_con_handle, "r" ); + *stdin = *fp; + setvbuf( stdin, NULL, _IONBF, 0 ); + } // redirect unbuffered STDERR to the console l_std_handle = (long)GetStdHandle(STD_ERROR_HANDLE); h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); - fp = _fdopen( h_con_handle, "w" ); - *stderr = *fp; - setvbuf( stderr, NULL, _IONBF, 0 ); + if (h_con_handle == -1) + { + llwarns << "create_console() failed to open stderr handle" << llendl; + } + else + { + fp = _fdopen( h_con_handle, "w" ); + *stderr = *fp; + setvbuf( stderr, NULL, _IONBF, 0 ); + } } LLAppViewerWin32::LLAppViewerWin32(const char* cmd_line) : diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index c08771c5e7..d7ba4ea470 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -384,18 +384,18 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) // Continuing the horrible hack above, we need to extract the originally requested permissions data, if any, // and use them for each next file to be uploaded. Note the requested perms are not the same as the U32 everyone_perms = - content.has("everyone_mask") ? - content["everyone_mask"].asInteger() : + content.has("new_everyone_mask") ? + content["new_everyone_mask"].asInteger() : PERM_NONE; U32 group_perms = - content.has("group_mask") ? - content["group_mask"].asInteger() : + content.has("new_group_mask") ? + content["new_group_mask"].asInteger() : PERM_NONE; U32 next_owner_perms = - content.has("next_owner_mask") ? - content["next_owner_mask"].asInteger() : + content.has("new_next_owner_mask") ? + content["new_next_owner_mask"].asInteger() : PERM_NONE; std::string display_name = LLStringUtil::null; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index cbbdcb2983..cbbdcb2983 100644..100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index f51552aae5..01d19c5ba0 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -46,6 +46,7 @@ #include "llhints.h" #include "llimfloater.h" // for LLIMFloater #include "llnearbychatbar.h" +#include "llnearbychatbarlistener.h" #include "llsidetray.h" #include "llspeakbutton.h" #include "llsplitbutton.h" @@ -537,6 +538,8 @@ BOOL LLBottomTray::postBuild() mNearbyChatBar = findChild<LLNearbyChatBar>("chat_bar"); LLHints::registerHintTarget("chat_bar", mNearbyChatBar->LLView::getHandle()); + mListener.reset(new LLNearbyChatBarListener(*mNearbyChatBar)); + mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel"); mNearbyCharResizeHandlePanel = getChild<LLPanel>("chat_bar_resize_handle_panel"); diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index d9c95d82e5..62718531ef 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -39,6 +39,7 @@ class LLIMChiclet; class LLBottomTrayLite; class LLLayoutPanel; class LLMenuGL; +class LLNearbyChatBarListener; // Build time optimization, generate once in .cpp file #ifndef LLBOTTOMTRAY_CPP @@ -555,6 +556,9 @@ protected: * Image used to show position where dragged button will be dropped. */ LLUIImage* mImageDragIndication; + + // We want only one LLNearbyChatBarListener object, so it's tied to this singleton + boost::shared_ptr<LLNearbyChatBarListener> mListener; }; #endif // LL_LLBOTTOMPANEL_H diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 6e58be8174..cf0374075a 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -671,6 +671,9 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl) } } + +/* Cruft - global gChatHandler declared below has been commented out, + so this class is never used. See similar code in llnearbychatbar.cpp class LLChatHandler : public LLCommandHandler { public: @@ -691,7 +694,7 @@ public: { S32 channel = tokens[0].asInteger(); // VWR-19499 Restrict function to chat channels greater than 0. - if ((channel > 0) && (channel < 2147483647)) + if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG)) { retval = true; // Say mesg on channel @@ -710,3 +713,4 @@ public: // Creating the object registers with the dispatcher. //LLChatHandler gChatHandler; +cruft */ diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 84c560639e..254c0adef1 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -317,7 +317,6 @@ BOOL LLCOFWearables::postBuild() mAttachments->setComparator(&WEARABLE_NAME_COMPARATOR); mBodyParts->setComparator(&WEARABLE_NAME_COMPARATOR); - mClothingTab = getChild<LLAccordionCtrlTab>("tab_clothing"); mClothingTab->setDropDownStateChangedCallback(boost::bind(&LLCOFWearables::onAccordionTabStateChanged, this, _1, _2)); @@ -499,6 +498,10 @@ void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel mAttachments->sort(); mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false) } + else + { + mAttachments->setNoItemsCommentText(LLTrans::getString("no_attachments")); + } if (mBodyParts->size()) { diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index 19dba3f917..19dba3f917 100644..100755 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index bdc12ec0e3..ad3710843c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -94,7 +94,9 @@ void LLDrawable::init() mRenderType = 0; mCurrentScale = LLVector3(1,1,1); mDistanceWRTCamera = 0.0f; - + mPositionGroup.clear(); + mExtents[0].clear(); + mExtents[1].clear(); mQuietCount = 0; mState = 0; @@ -587,7 +589,10 @@ void LLDrawable::setRadius(F32 radius) void LLDrawable::moveUpdatePipeline(BOOL moved) { - makeActive(); + if (moved) + { + makeActive(); + } // Update the face centers. for (S32 i = 0; i < getNumFaces(); i++) @@ -695,7 +700,8 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { - llerrs << "WTF?" << llendl; + llwarns << "Attempted to update distance for non-world camera." << llendl; + return; } //switch LOD with the spatial group to avoid artifacts diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 9ebe1a45b4..e268640a21 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -276,6 +276,7 @@ public: REBUILD_SHADOW = 0x02000000, HAS_ALPHA = 0x04000000, RIGGED = 0x08000000, + PARTITION_MOVE = 0x10000000, } EDrawableFlags; private: //aligned members diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 25e4bc847c..f5483d969d 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -191,6 +191,16 @@ void LLDrawPool::renderPostDeferred(S32 pass) //virtual void LLDrawPool::endRenderPass( S32 pass ) { + for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++) + { //dummy cleanup of any currently bound textures + if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) + { + gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); + gGL.getTexUnit(i)->disable(); + } + } + + gGL.getTexUnit(0)->activate(); } //virtual @@ -430,14 +440,14 @@ void LLRenderPass::renderTexture(U32 type, U32 mask) pushBatches(type, mask, TRUE); } -void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture) +void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) { for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; if (pparams) { - pushBatch(*pparams, mask, texture); + pushBatch(*pparams, mask, texture, batch_textures); } } } @@ -456,26 +466,43 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params) } } -void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) { applyModelMatrix(params); + bool tex_setup = false; + if (texture) { - if (params.mTexture.notNull()) + if (batch_textures && params.mTextureList.size() > 1) { - params.mTexture->addTextureStats(params.mVSize); - gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; - if (params.mTextureMatrix) + for (U32 i = 0; i < params.mTextureList.size(); ++i) { - glMatrixMode(GL_TEXTURE); - glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; + if (params.mTextureList[i].notNull()) + { + gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); + } } } else - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + { //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTexture.notNull()) + { + params.mTexture->addTextureStats(params.mVSize); + gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; + if (params.mTextureMatrix) + { + tex_setup = true; + gGL.getTexUnit(0)->activate(); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + } + else + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } } } @@ -490,7 +517,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); } - if (params.mTextureMatrix && texture && params.mTexture.notNull()) + if (tex_setup) { glLoadIdentity(); glMatrixMode(GL_MODELVIEW); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index d3fd9ead0d..c7acbb42c6 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -146,8 +146,8 @@ public: void resetDrawOrders() { } static void applyModelMatrix(LLDrawInfo& params); - virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE); - virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); + virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); + virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE); virtual void renderTexture(U32 type, U32 mask); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 8b5a2ce781..8d46133912 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -124,7 +124,10 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) if (pass == 0) { simple_shader = &gDeferredAlphaProgram; - fullbright_shader = &gDeferredFullbrightProgram; + fullbright_shader = &gObjectFullbrightProgram; + + //prime simple shader (loads shadow relevant uniforms) + gPipeline.bindDeferredShader(*simple_shader); } else { @@ -228,13 +231,13 @@ void LLDrawPoolAlpha::render(S32 pass) if (!LLPipeline::sRenderDeferred) { simple_shader->bind(); - pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); + pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } if (fullbright_shader) { fullbright_shader->bind(); } - pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask()); + pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); LLGLSLShader::bindNoShader(); } else @@ -273,7 +276,14 @@ void LLDrawPoolAlpha::render(S32 pass) } } - renderAlpha(getVertexDataMask()); + if (mVertexShaderLevel > 0) + { + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX); + } + else + { + renderAlpha(getVertexDataMask()); + } gGL.setColorMask(true, false); @@ -283,11 +293,6 @@ void LLDrawPoolAlpha::render(S32 pass) gGL.setSceneBlendType(LLRender::BT_ALPHA); } - if (deferred_render && current_shader != NULL) - { - gPipeline.unbindDeferredShader(*current_shader); - } - if (sShowDebugAlpha) { if(gPipeline.canUseWindLightShaders()) @@ -339,12 +344,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; - S32 diffuse_channel = 0; - - BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) - || gPipeline.canUseWindLightShadersOnObjects(); - + BOOL use_shaders = gPipeline.canUseVertexShaders(); + for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; @@ -368,92 +370,89 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) LLRenderPass::applyModelMatrix(params); + + if (params.mFullbright) { - if (params.mFullbright) - { - // Turn off lighting if it hasn't already been so. - if (light_enabled || !initialized_lighting) - { - initialized_lighting = TRUE; - if (use_shaders) - { - target_shader = fullbright_shader; - } - else - { - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); - } - light_enabled = FALSE; - } - } - // Turn on lighting if it isn't already. - else if (!light_enabled || !initialized_lighting) + // Turn off lighting if it hasn't already been so. + if (light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { - target_shader = simple_shader; + target_shader = fullbright_shader; } else { - gPipeline.enableLightsDynamic(); + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } - light_enabled = TRUE; + light_enabled = FALSE; } - - // If we need shaders, and we're not ALREADY using the proper shader, then bind it - // (this way we won't rebind shaders unnecessarily). - if(use_shaders && (current_shader != target_shader)) + } + // Turn on lighting if it isn't already. + else if (!light_enabled || !initialized_lighting) + { + initialized_lighting = TRUE; + if (use_shaders) { - llassert(target_shader != NULL); - 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 - { - current_shader->bind(); - } + target_shader = simple_shader; } - else if (!use_shaders && current_shader != NULL) + else { - if (deferred_render) - { - gPipeline.unbindDeferredShader(*current_shader); - diffuse_channel = 0; - } - LLGLSLShader::bindNoShader(); - current_shader = NULL; + gPipeline.enableLightsDynamic(); } + light_enabled = TRUE; + } - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } + // If we need shaders, and we're not ALREADY using the proper shader, then bind it + // (this way we won't rebind shaders unnecessarily). + if(use_shaders && (current_shader != target_shader)) + { + llassert(target_shader != NULL); + current_shader = target_shader; + current_shader->bind(); + } + else if (!use_shaders && current_shader != NULL) + { + LLGLSLShader::bindNoShader(); + current_shader = NULL; + } - - if (params.mTexture.notNull()) + if (params.mGroup) + { + params.mGroup->rebuildMesh(); + } + + bool tex_setup = false; + + if (use_shaders && params.mTextureList.size() > 1) + { + for (U32 i = 0; i < params.mTextureList.size(); ++i) { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); - if(params.mTexture.notNull()) + if (params.mTextureList[i].notNull()) { - params.mTexture->addTextureStats(params.mVSize); + gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); } + } + } + else + { //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTexture.notNull()) + { + params.mTexture->addTextureStats(params.mVSize); + gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; if (params.mTextureMatrix) { + tex_setup = true; gGL.getTexUnit(0)->activate(); glMatrixMode(GL_TEXTURE); glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); gPipeline.mTextureMatrixOps++; } } + else + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } } params.mVertexBuffer->setBuffer(mask); @@ -480,7 +479,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); } - if (params.mTextureMatrix && params.mTexture.notNull()) + if (tex_setup) { gGL.getTexUnit(0)->activate(); glLoadIdentity(); @@ -490,15 +489,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } - if (deferred_render && current_shader != NULL) - { - gPipeline.unbindDeferredShader(*current_shader); - LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - } - + LLVertexBuffer::unbind(); + if (!light_enabled) { gPipeline.enableLightsDynamic(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 645c7ebcae..9f790d03fe 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -459,14 +459,6 @@ S32 LLDrawPoolAvatar::getNumPasses() { return 10; } - if (LLPipeline::sImpostorRender) - { - return 1; - } - else - { - return 3; - } } @@ -613,11 +605,11 @@ void LLDrawPoolAvatar::beginRigid() { if (LLPipeline::sUnderWaterRender) { - sVertexProgram = &gObjectSimpleWaterProgram; + sVertexProgram = &gObjectSimpleNonIndexedWaterProgram; } else { - sVertexProgram = &gObjectSimpleProgram; + sVertexProgram = &gObjectSimpleNonIndexedProgram; } if (sVertexProgram != NULL) @@ -669,7 +661,7 @@ void LLDrawPoolAvatar::endDeferredImpostor() void LLDrawPoolAvatar::beginDeferredRigid() { - sVertexProgram = &gDeferredDiffuseProgram; + sVertexProgram = &gDeferredNonIndexedDiffuseProgram; sVertexProgram->bind(); } @@ -700,11 +692,11 @@ void LLDrawPoolAvatar::beginSkinned() { if (LLPipeline::sUnderWaterRender) { - sVertexProgram = &gObjectSimpleWaterProgram; + sVertexProgram = &gObjectSimpleNonIndexedWaterProgram; } else { - sVertexProgram = &gObjectSimpleProgram; + sVertexProgram = &gObjectSimpleNonIndexedProgram; } } @@ -789,11 +781,11 @@ void LLDrawPoolAvatar::beginRiggedSimple() { if (LLPipeline::sUnderWaterRender) { - sVertexProgram = &gObjectSimpleWaterProgram; + sVertexProgram = &gObjectSimpleNonIndexedWaterProgram; } else { - sVertexProgram = &gObjectSimpleProgram; + sVertexProgram = &gObjectSimpleNonIndexedProgram; } } @@ -864,11 +856,11 @@ void LLDrawPoolAvatar::beginRiggedFullbright() { if (LLPipeline::sUnderWaterRender) { - sVertexProgram = &gObjectFullbrightWaterProgram; + sVertexProgram = &gObjectFullbrightNonIndexedWaterProgram; } else { - sVertexProgram = &gObjectFullbrightProgram; + sVertexProgram = &gObjectFullbrightNonIndexedProgram; } } @@ -908,11 +900,11 @@ void LLDrawPoolAvatar::beginRiggedShinySimple() { if (LLPipeline::sUnderWaterRender) { - sVertexProgram = &gObjectShinyWaterProgram; + sVertexProgram = &gObjectShinyNonIndexedWaterProgram; } else { - sVertexProgram = &gObjectShinyProgram; + sVertexProgram = &gObjectShinyNonIndexedProgram; } } @@ -953,11 +945,11 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny() { if (LLPipeline::sUnderWaterRender) { - sVertexProgram = &gObjectFullbrightShinyWaterProgram; + sVertexProgram = &gObjectFullbrightShinyNonIndexedWaterProgram; } else { - sVertexProgram = &gObjectFullbrightShinyProgram; + sVertexProgram = &gObjectFullbrightShinyNonIndexedProgram; } } @@ -1419,7 +1411,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { - if (avatar->isSelf() && !gAgent.needsRenderAvatar()) + if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled()) { return; } @@ -1456,7 +1448,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) continue; } - const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id); + const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, vobj); if (!skin) { continue; diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 29b50761d8..813b3820ee 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -94,6 +94,13 @@ void LLStandardBumpmap::restoreGL() // static void LLStandardBumpmap::addstandard() { + if(!gTextureList.isInitialized()) + { + //Note: loading pre-configuration sometimes triggers this call. + //But it is safe to return here because bump images will be reloaded during initialization later. + return ; + } + // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps. //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); clear(); @@ -309,6 +316,9 @@ void LLDrawPoolBump::endRenderPass(S32 pass) llassert(0); break; } + + //to cleanup texture channels + LLRenderPass::endRenderPass(pass); } //static @@ -347,6 +357,11 @@ void LLDrawPoolBump::beginShiny(bool invisible) } bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); + + if (mVertexShaderLevel > 1) + { //indexed texture rendering, channel 0 is always diffuse + diffuse_channel = 0; + } } //static @@ -414,16 +429,16 @@ void LLDrawPoolBump::renderShiny(bool invisible) LLGLEnable blend_enable(GL_BLEND); if (!invisible && mVertexShaderLevel > 1) { - LLRenderPass::renderTexture(LLRenderPass::PASS_SHINY, sVertexMask); + LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } else if (!invisible) { renderGroups(LLRenderPass::PASS_SHINY, sVertexMask); } - else // invisible - { - renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); - } + //else // invisible (deprecated) + //{ + //renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); + //} } } @@ -522,6 +537,12 @@ void LLDrawPoolBump::beginFullbrightShiny() gGL.getTexUnit(cube_channel)->bind(cube_map); gGL.getTexUnit(0)->activate(); } + + if (mVertexShaderLevel > 1) + { //indexed texture rendering, channel 0 is always diffuse + diffuse_channel = 0; + } + mShiny = TRUE; } @@ -536,7 +557,15 @@ void LLDrawPoolBump::renderFullbrightShiny() if( gSky.mVOSkyp->getCubeMap() ) { LLGLEnable blend_enable(GL_BLEND); - LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); + + if (mVertexShaderLevel > 1) + { + LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + } + else + { + LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); + } } } @@ -836,6 +865,9 @@ void LLDrawPoolBump::endPostDeferredPass(S32 pass) endBump(LLRenderPass::PASS_POST_BUMP); break; } + + //to disable texture channels + LLRenderPass::endRenderPass(pass); } void LLDrawPoolBump::renderPostDeferred(S32 pass) @@ -889,9 +921,10 @@ void LLBumpImageList::destroyGL() void LLBumpImageList::restoreGL() { - if(!gTextureList.isInitialized())
- {
- return ;
+ if(!gTextureList.isInitialized()) + { + //safe to return here because bump images will be reloaded during initialization later. + return ; } LLStandardBumpmap::restoreGL(); @@ -1292,43 +1325,60 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask) } } -void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) { applyModelMatrix(params); - if (params.mTextureMatrix) + bool tex_setup = false; + + if (batch_textures && params.mTextureList.size() > 1) { - if (mShiny) + for (U32 i = 0; i < params.mTextureList.size(); ++i) { - gGL.getTexUnit(0)->activate(); - glMatrixMode(GL_TEXTURE); + if (params.mTextureList[i].notNull()) + { + gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); + } } - else + } + else + { //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTextureMatrix) { - gGL.getTexUnit(1)->activate(); - glMatrixMode(GL_TEXTURE); + if (mShiny) + { + gGL.getTexUnit(0)->activate(); + glMatrixMode(GL_TEXTURE); + } + else + { + gGL.getTexUnit(1)->activate(); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + gGL.getTexUnit(0)->activate(); + } + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); gPipeline.mTextureMatrixOps++; - gGL.getTexUnit(0)->activate(); - } - glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - } - - if (mShiny && mVertexShaderLevel > 1 && texture) - { - if (params.mTexture.notNull()) - { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ; - params.mTexture->addTextureStats(params.mVSize); + tex_setup = true; } - else + + if (mShiny && mVertexShaderLevel > 1 && texture) { - gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); + if (params.mTexture.notNull()) + { + gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ; + params.mTexture->addTextureStats(params.mVSize); + } + else + { + gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); + } } } - + if (params.mGroup) { params.mGroup->rebuildMesh(); @@ -1336,7 +1386,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); - if (params.mTextureMatrix) + if (tex_setup) { if (mShiny) { diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index f4702bf61d..476b1d41b7 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -55,7 +55,7 @@ public: virtual void endRenderPass( S32 pass ); virtual S32 getNumPasses(); /*virtual*/ void prerender(); - /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); + /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); void renderBump(U32 type, U32 mask); void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 2e83167851..5dbb27cabb 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -44,6 +44,36 @@ static LLGLSLShader* fullbright_shader = NULL; static LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple"); static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass"); +void LLDrawPoolGlow::beginPostDeferredPass(S32 pass) +{ + gDeferredFullbrightProgram.bind(); +} + +void LLDrawPoolGlow::renderPostDeferred(S32 pass) +{ + LLFastTimer t(FTM_RENDER_GLOW); + LLGLEnable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.flush(); + /// Get rid of z-fighting with non-glow pass. + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -1.0f); + gGL.setSceneBlendType(LLRender::BT_ADD); + + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.setColorMask(false, true); + pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + gGL.setColorMask(true, false); + gGL.setSceneBlendType(LLRender::BT_ALPHA); +} + +void LLDrawPoolGlow::endPostDeferredPass(S32 pass) +{ + gDeferredFullbrightProgram.unbind(); + LLRenderPass::endRenderPass(pass); +} + void LLDrawPoolGlow::render(S32 pass) { LLFastTimer t(FTM_RENDER_GLOW); @@ -68,7 +98,15 @@ void LLDrawPoolGlow::render(S32 pass) LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.setColorMask(false, true); - renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask()); + + if (shader_level > 1) + { + pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + } + else + { + renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask()); + } gGL.setColorMask(true, false); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -79,10 +117,10 @@ void LLDrawPoolGlow::render(S32 pass) } } -void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) { glColor4ubv(params.mGlowColor.mV); - LLRenderPass::pushBatch(params, mask, texture); + LLRenderPass::pushBatch(params, mask, texture, batch_textures); } @@ -126,10 +164,11 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass) void LLDrawPoolSimple::endRenderPass(S32 pass) { LLFastTimer t(FTM_RENDER_SIMPLE); + stop_glerror(); LLRenderPass::endRenderPass(pass); - - if (mVertexShaderLevel > 0){ - + stop_glerror(); + if (mVertexShaderLevel > 0) + { simple_shader->unbind(); } } @@ -142,13 +181,24 @@ void LLDrawPoolSimple::render(S32 pass) { //render simple LLFastTimer t(FTM_RENDER_SIMPLE); gPipeline.enableLightsDynamic(); - renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); - if (LLPipeline::sRenderDeferred) - { //if deferred rendering is enabled, bump faces aren't registered as simple - //render bump faces here as simple so bump faces will appear under water - renderTexture(LLRenderPass::PASS_BUMP, getVertexDataMask()); + if (mVertexShaderLevel > 0) + { + U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; + + pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); + + if (LLPipeline::sRenderDeferred) + { //if deferred rendering is enabled, bump faces aren't registered as simple + //render bump faces here as simple so bump faces will appear under water + pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); + } + } + else + { + renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); } + } } @@ -177,7 +227,7 @@ void LLDrawPoolSimple::renderDeferred(S32 pass) { //render simple LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED); - renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); + pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } } @@ -200,11 +250,11 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass) if (LLPipeline::sUnderWaterRender) { - simple_shader = &gObjectSimpleWaterProgram; + simple_shader = &gObjectSimpleNonIndexedWaterProgram; } else { - simple_shader = &gObjectSimpleProgram; + simple_shader = &gObjectSimpleNonIndexedProgram; } if (mVertexShaderLevel > 0) @@ -285,6 +335,26 @@ void LLDrawPoolFullbright::prerender() mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } +void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) +{ + gDeferredFullbrightProgram.bind(); +} + +void LLDrawPoolFullbright::renderPostDeferred(S32 pass) +{ + LLFastTimer t(FTM_RENDER_FULLBRIGHT); + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; + pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); +} + +void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) +{ + gDeferredFullbrightProgram.unbind(); + LLRenderPass::endRenderPass(pass); +} + void LLDrawPoolFullbright::beginRenderPass(S32 pass) { LLFastTimer t(FTM_RENDER_FULLBRIGHT); @@ -313,25 +383,21 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass) void LLDrawPoolFullbright::render(S32 pass) { //render fullbright LLFastTimer t(FTM_RENDER_FULLBRIGHT); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + if (mVertexShaderLevel > 0) { fullbright_shader->bind(); fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; + pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); } else { gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR; + renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); } - - //gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f); - - //LLGLEnable test(GL_ALPHA_TEST); - //LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR; - renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); - - //gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } S32 LLDrawPoolFullbright::getNumPasses() diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index 5f3bbebbda..3811b3d398 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -98,9 +98,9 @@ public: LLDrawPoolFullbright(); /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } - /*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } - /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } - /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } + /*virtual*/ void beginPostDeferredPass(S32 pass); + /*virtual*/ void endPostDeferredPass(S32 pass); + /*virtual*/ void renderPostDeferred(S32 pass); /*virtual*/ void beginRenderPass(S32 pass); /*virtual*/ void endRenderPass(S32 pass); @@ -126,12 +126,12 @@ public: virtual void prerender() { } /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } - /*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } - /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } - /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } + /*virtual*/ void beginPostDeferredPass(S32 pass); + /*virtual*/ void endPostDeferredPass(S32 pass); + /*virtual*/ void renderPostDeferred(S32 pass); void render(S32 pass = 0); - void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE); + void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); }; diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 195ee60a2e..81c796b146 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -66,11 +66,11 @@ void LLDrawPoolTree::beginRenderPass(S32 pass) if (LLPipeline::sUnderWaterRender) { - shader = &gObjectSimpleWaterProgram; + shader = &gObjectSimpleNonIndexedWaterProgram; } else { - shader = &gObjectSimpleProgram; + shader = &gObjectSimpleNonIndexedProgram; } if (gPipeline.canUseWindLightShadersOnObjects()) diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 696c2d1abd..409b18d522 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -44,6 +44,8 @@ LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL; LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; +static LLGLSLShader* cloud_shader = NULL; +static LLGLSLShader* sky_shader = NULL; LLDrawPoolWLSky::LLDrawPoolWLSky(void) : @@ -83,12 +85,32 @@ LLViewerTexture *LLDrawPoolWLSky::getDebugTexture() void LLDrawPoolWLSky::beginRenderPass( S32 pass ) { + sky_shader = + LLPipeline::sUnderWaterRender ? + &gObjectSimpleWaterProgram : + &gWLSkyProgram; + + cloud_shader = + LLPipeline::sUnderWaterRender ? + &gObjectSimpleWaterProgram : + &gWLCloudProgram; } void LLDrawPoolWLSky::endRenderPass( S32 pass ) { } +void LLDrawPoolWLSky::beginDeferredPass(S32 pass) +{ + sky_shader = &gDeferredWLSkyProgram; + cloud_shader = &gDeferredWLCloudProgram; +} + +void LLDrawPoolWLSky::endDeferredPass(S32 pass) +{ + +} + void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const { LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); @@ -128,19 +150,14 @@ void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const { if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) { - LLGLSLShader* shader = - LLPipeline::sUnderWaterRender ? - &gObjectSimpleWaterProgram : - &gWLSkyProgram; - LLGLDisable blend(GL_BLEND); - shader->bind(); + sky_shader->bind(); /// Render the skydome - renderDome(camHeightLocal, shader); + renderDome(camHeightLocal, sky_shader); - shader->unbind(); + sky_shader->unbind(); } } @@ -186,23 +203,18 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const { if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)) { - LLGLSLShader* shader = - LLPipeline::sUnderWaterRender ? - &gObjectSimpleWaterProgram : - &gWLCloudProgram; - LLGLEnable blend(GL_BLEND); gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.getTexUnit(0)->bind(sCloudNoiseTexture); - shader->bind(); + cloud_shader->bind(); /// Render the skydome - renderDome(camHeightLocal, shader); + renderDome(camHeightLocal, cloud_shader); - shader->unbind(); + cloud_shader->unbind(); } } @@ -246,6 +258,53 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() } } +void LLDrawPoolWLSky::renderDeferred(S32 pass) +{ + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) + { + return; + } + LLFastTimer ftm(FTM_RENDER_WL_SKY); + + const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius(); + + LLGLSNoFog disableFog; + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + LLGLDisable clip(GL_CLIP_PLANE0); + + gGL.setColorMask(true, false); + + LLGLSquashToFarClip far_clip(glh_get_current_projection()); + + renderSkyHaze(camHeightLocal); + + LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); + glPushMatrix(); + + + glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); + + gDeferredStarProgram.bind(); + // *NOTE: have to bind a texture here since register combiners blending in + // renderStars() requires something to be bound and we might as well only + // bind the moon's texture once. + gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture()); + + renderHeavenlyBodies(); + + renderStars(); + + gDeferredStarProgram.unbind(); + + glPopMatrix(); + + renderSkyClouds(camHeightLocal); + + gGL.setColorMask(true, true); + //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +} + void LLDrawPoolWLSky::render(S32 pass) { if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index 8ca1ebb942..cd15c991ee 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -44,10 +44,10 @@ public: /*virtual*/ BOOL isDead() { return FALSE; } - /*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } - /*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } - /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } - /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } + /*virtual*/ S32 getNumDeferredPasses() { return 1; } + /*virtual*/ void beginDeferredPass(S32 pass); + /*virtual*/ void endDeferredPass(S32 pass); + /*virtual*/ void renderDeferred(S32 pass); /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ void beginRenderPass( S32 pass ); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 5398c13c44..b6566fcbd0 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -165,6 +165,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mIndexInTex = 0; mTexture = NULL; mTEOffset = -1; + mTextureIndex = 255; setDrawable(drawablep); mVObjp = objp; @@ -364,14 +365,7 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align) //allocate vertices in blocks of 4 for alignment num_vertices = (num_vertices + 0x3) & ~0x3; } - else - { - if (mDrawablep->getVOVolume()) - { - llerrs << "WTF?" << llendl; - } - } - + if (mGeomCount != num_vertices || mIndicesCount != num_indices) { @@ -393,6 +387,26 @@ void LLFace::setGeomIndex(U16 idx) } } +void LLFace::setTextureIndex(U8 index) +{ + if (index != mTextureIndex) + { + mTextureIndex = index; + + if (mTextureIndex != 255) + { + mDrawablep->setState(LLDrawable::REBUILD_POSITION); + } + else + { + if (mDrawInfo && !mDrawInfo->mTextureList.empty()) + { + llerrs << "Face with no texture index references indexed texture draw info." << llendl; + } + } + } +} + void LLFace::setIndicesIndex(S32 idx) { if (mIndicesIndex != idx) @@ -415,11 +429,11 @@ U16 LLFace::getGeometryAvatar( if (mVertexBuffer.notNull()) { - mVertexBuffer->getVertexStrider (vertices, mGeomIndex); - mVertexBuffer->getNormalStrider (normals, mGeomIndex); - mVertexBuffer->getTexCoord0Strider (tex_coords, mGeomIndex); - mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex); - mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex); + mVertexBuffer->getVertexStrider (vertices, mGeomIndex, mGeomCount); + mVertexBuffer->getNormalStrider (normals, mGeomIndex, mGeomCount); + mVertexBuffer->getTexCoord0Strider (tex_coords, mGeomIndex, mGeomCount); + mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex, mGeomCount); + mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex, mGeomCount); } return mGeomIndex; @@ -432,17 +446,17 @@ U16 LLFace::getGeometry(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &no if (mVertexBuffer.notNull()) { - mVertexBuffer->getVertexStrider(vertices, mGeomIndex); + mVertexBuffer->getVertexStrider(vertices, mGeomIndex, mGeomCount); if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) { - mVertexBuffer->getNormalStrider(normals, mGeomIndex); + mVertexBuffer->getNormalStrider(normals, mGeomIndex, mGeomCount); } if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD0)) { - mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex); + mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); } - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); } return mGeomIndex; @@ -679,6 +693,19 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of } +bool less_than_max_mag(const LLVector4a& vec) +{ + LLVector4a MAX_MAG; + MAX_MAG.splat(1024.f*1024.f); + + LLVector4a val; + val.setAbs(vec); + + S32 lt = val.lessThan(MAX_MAG).getGatheredBits() & 0x7; + + return lt == 0x7; +} + BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume) { @@ -713,6 +740,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, min = face.mExtents[0]; max = face.mExtents[1]; + llassert(less_than_max_mag(min)); + llassert(less_than_max_mag(max)); //min, max are in volume space, convert to drawable render space LLVector4a center; @@ -724,6 +753,9 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, size.setSub(max, min); size.mul(0.5f); + llassert(less_than_max_mag(min)); + llassert(less_than_max_mag(max)); + if (!global_volume) { //VECTORIZE THIS @@ -761,6 +793,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, newMin = newMax = center; + llassert(less_than_max_mag(center)); + for (U32 i = 0; i < 4; i++) { LLVector4a delta; @@ -772,6 +806,9 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, newMin.setMin(newMin,min); newMax.setMax(newMax,max); + + llassert(less_than_max_mag(newMin)); + llassert(less_than_max_mag(newMax)); } if (!mDrawablep->isActive()) @@ -780,14 +817,22 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, offset.load3(mDrawablep->getRegion()->getOriginAgent().mV); newMin.add(offset); newMax.add(offset); + + llassert(less_than_max_mag(newMin)); + llassert(less_than_max_mag(newMax)); } t.setAdd(newMin, newMax); t.mul(0.5f); + llassert(less_than_max_mag(t)); + //VECTORIZE THIS mCenterLocal.set(t.getF32ptr()); + llassert(less_than_max_mag(newMin)); + llassert(less_than_max_mag(newMax)); + t.setSub(newMax,newMin); mBoundingSphereRadius = t.getLength3().getF32()*0.5f; @@ -1078,27 +1123,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, const LLTextureEntry *tep = mVObjp->getTE(f); const U8 bump_code = tep ? tep->getBumpmap() : 0; - if (rebuild_pos) - { - mVertexBuffer->getVertexStrider(vert, mGeomIndex); - vertices = (LLVector4a*) vert.get(); - } - if (rebuild_normal) - { - mVertexBuffer->getNormalStrider(norm, mGeomIndex); - normals = (LLVector4a*) norm.get(); - } - if (rebuild_binormal) - { - mVertexBuffer->getBinormalStrider(binorm, mGeomIndex); - binormals = (LLVector4a*) binorm.get(); - } - if (rebuild_weights) - { - mVertexBuffer->getWeight4Strider(wght, mGeomIndex); - weights = (LLVector4a*) wght.get(); - } - F32 tcoord_xoffset = 0.f ; F32 tcoord_yoffset = 0.f ; F32 tcoord_xscale = 1.f ; @@ -1107,12 +1131,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_tcoord) { - mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex); - if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) - { - mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex); - } - in_atlas = isAtlasInUse() ; if(in_atlas) { @@ -1125,11 +1143,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, tcoord_yscale = tmp->mV[1] ; } } - if (rebuild_color) - { - mVertexBuffer->getColorStrider(colors, mGeomIndex); - } - + BOOL is_static = mDrawablep->isStatic(); BOOL is_global = is_static; @@ -1168,7 +1182,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, // INDICES if (full_rebuild) { - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, true); + __m128i* dst = (__m128i*) indicesp.get(); __m128i* src = (__m128i*) vf.mIndices; __m128i offset = _mm_set1_epi16(index_offset); @@ -1185,6 +1200,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { indicesp[i] = vf.mIndices[i]+index_offset; } + + mVertexBuffer->setBuffer(0); } LLMatrix4a mat_normal; @@ -1330,6 +1347,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (!in_atlas && !do_bump) { //not in atlas or not bump mapped, might be able to do a cheap update + mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); + if (texgen != LLTextureEntry::TEX_GEN_PLANAR) { if (!do_tex_mat) @@ -1402,9 +1421,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } } + + mVertexBuffer->setBuffer(0); } else { //either bump mapped or in atlas, just do the whole expensive loop + mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, true); + + std::vector<LLVector2> bump_tc; + for (S32 i = 0; i < num_vertices; i++) { LLVector2 tc(vf.mTexCoords[i]); @@ -1535,8 +1560,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, *tex_coords++ = tc; - - if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) + if (do_bump) + { + bump_tc.push_back(tc); + } + } + + mVertexBuffer->setBuffer(0); + + + if (do_bump) + { + mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, true); + + for (S32 i = 0; i < num_vertices; i++) { LLVector4a tangent; tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); @@ -1558,16 +1595,22 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } binormal.normalize3fast(); + LLVector2 tc = bump_tc[i]; tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); *tex_coords2++ = tc; - } + } + + mVertexBuffer->setBuffer(0); } } } if (rebuild_pos) { + mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, true); + vertices = (LLVector4a*) vert.get(); + LLMatrix4a mat_vert; mat_vert.loadu(mat_vert_in); @@ -1580,10 +1623,28 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mat_vert.affineTransform(*src++, *dst++); } while(dst < end); + + F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); + F32 *index_dst = (F32*) vertices; + F32 *index_end = (F32*) end; + + index_dst += 3; + index_end += 3; + do + { + *index_dst = index; + index_dst += 4; + } + while (index_dst < index_end); + + mVertexBuffer->setBuffer(0); } if (rebuild_normal) { + mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, true); + normals = (LLVector4a*) norm.get(); + for (S32 i = 0; i < num_vertices; i++) { LLVector4a normal; @@ -1591,10 +1652,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, normal.normalize3fast(); normals[i] = normal; } + + mVertexBuffer->setBuffer(0); } if (rebuild_binormal) { + mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, true); + binormals = (LLVector4a*) binorm.get(); + for (S32 i = 0; i < num_vertices; i++) { LLVector4a binormal; @@ -1602,15 +1668,22 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, binormal.normalize3fast(); binormals[i] = binormal; } + + mVertexBuffer->setBuffer(0); } if (rebuild_weights && vf.mWeights) { + mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, true); + weights = (LLVector4a*) wght.get(); LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); + mVertexBuffer->setBuffer(0); } if (rebuild_color) { + mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, true); + LLVector4a src; U32 vec[4]; @@ -1629,6 +1702,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { dst[i] = src; } + + mVertexBuffer->setBuffer(0); } if (rebuild_tcoord) @@ -2045,13 +2120,13 @@ S32 LLFace::getColors(LLStrider<LLColor4U> &colors) } // llassert(mGeomIndex >= 0); - mVertexBuffer->getColorStrider(colors, mGeomIndex); + mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount); return mGeomIndex; } S32 LLFace::getIndices(LLStrider<U16> &indicesp) { - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); llassert(indicesp[0] != indicesp[1]); return mIndicesIndex; } diff --git a/indra/newview/llface.h b/indra/newview/llface.h index b2170c4cf3..b5eaeecd60 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -94,6 +94,8 @@ public: U16 getGeomCount() const { return mGeomCount; } // vertex count for this face U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool U16 getGeomStart() const { return mGeomIndex; } // index into draw pool + void setTextureIndex(U8 index); + U8 getTextureIndex() const { return mTextureIndex; } void setTexture(LLViewerTexture* tex) ; void switchTexture(LLViewerTexture* new_texture); void dirtyTexture(); @@ -262,6 +264,7 @@ private: U16 mGeomCount; // vertex count for this face U16 mGeomIndex; // index into draw pool + U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing U32 mIndicesCount; U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!) S32 mIndexInTex ; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 3bdab75acf..83844048d1 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -765,7 +765,7 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("OpenGLPre30"); } - if (gGLManager.mNumTextureUnits <= 8) + if (gGLManager.mNumTextureImageUnits <= 8) { maskFeatures("TexUnit8orLess"); } diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index 2c4153688a..a9f52282a5 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -131,7 +131,7 @@ void LLFirstUse::notMoving(bool enable) // static void LLFirstUse::viewPopup(bool enable) { - firstUseNotification("FirstViewPopup", enable, "HintView", LLSD(), LLSD().with("target", "view_popup").with("direction", "right")); +// firstUseNotification("FirstViewPopup", enable, "HintView", LLSD(), LLSD().with("target", "view_popup").with("direction", "right")); } // static diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 3d1650d2f5..32a533570a 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -366,7 +366,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate() LLFastTimer ftm(FTM_DO_FLEXIBLE_UPDATE); LLVolume* volume = mVO->getVolume(); LLPath *path = &volume->getPath(); - if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible()) // if its uninitialized but not visible, what then? - Nyx + if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible()) { mVO->markForUpdate(TRUE); if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0)) @@ -375,7 +375,11 @@ void LLVolumeImplFlexible::doFlexibleUpdate() } } - llassert_always(mInitialized); + if(!mInitialized) + { + //the object is not visible + return ; + } S32 num_sections = 1 << mSimulateRes; diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 50b19a4221..610142b5a9 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -461,15 +461,15 @@ void LLFloaterBuyLandUI::updateParcelInfo() if (!authorizedBuyer.isNull() && buyer != authorizedBuyer) { - // Maybe the parcel is set for sale to a group we are in.
- bool authorized_group =
- gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_DEED)
- && gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_SET_SALE_INFO);
-
- if (!authorized_group)
- {
- mCannotBuyReason = getString("set_to_sell_to_other");
- return;
+ // Maybe the parcel is set for sale to a group we are in. + bool authorized_group = + gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_DEED) + && gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_SET_SALE_INFO); + + if (!authorized_group) + { + mCannotBuyReason = getString("set_to_sell_to_other"); + return; } } } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index e8da1aa42c..ab6753b4be 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -98,7 +98,8 @@ #include "llvfile.h" #include "llvfs.h" #include "llcallbacklist.h" - +#include "llviewerobjectlist.h" +#include "llanimationstates.h" #include "glod/glod.h" //static @@ -177,6 +178,80 @@ std::string lod_label_name[NUM_LOD+1] = "I went off the end of the lod_label_name array. Me so smart." }; + +#define LL_DEGENERACY_TOLERANCE 1e-7f + +inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b) +{ + volatile F32 p0 = a[0] * b[0]; + volatile F32 p1 = a[1] * b[1]; + volatile F32 p2 = a[2] * b[2]; + return p0 + p1 + p2; +} + +bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE) +{ + // small area check + { + LLVector4a edge1; edge1.setSub( a, b ); + LLVector4a edge2; edge2.setSub( a, c ); + ////////////////////////////////////////////////////////////////////////// + /// Linden Modified + ////////////////////////////////////////////////////////////////////////// + + // If no one edge is more than 10x longer than any other edge, we weaken + // the tolerance by a factor of 1e-4f. + + LLVector4a edge3; edge3.setSub( c, b ); + const F32 len1sq = edge1.dot3(edge1).getF32(); + const F32 len2sq = edge2.dot3(edge2).getF32(); + const F32 len3sq = edge3.dot3(edge3).getF32(); + bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq); + bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq); + bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq); + if ( abOK && acOK && cbOK ) + { + tolerance *= 1e-4f; + } + + ////////////////////////////////////////////////////////////////////////// + /// End Modified + ////////////////////////////////////////////////////////////////////////// + + LLVector4a cross; cross.setCross3( edge1, edge2 ); + + LLVector4a edge1b; edge1b.setSub( b, a ); + LLVector4a edge2b; edge2b.setSub( b, c ); + LLVector4a crossb; crossb.setCross3( edge1b, edge2b ); + + if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance )) + { + return true; + } + } + + // point triangle distance check + { + LLVector4a Q; Q.setSub(a, b); + LLVector4a R; R.setSub(c, b); + + const F32 QQ = dot3fpu(Q, Q); + const F32 RR = dot3fpu(R, R); + const F32 QR = dot3fpu(R, Q); + + volatile F32 QQRR = QQ * RR; + volatile F32 QRQR = QR * QR; + F32 Det = (QQRR - QRQR); + + if( Det == 0.0f ) + { + return true; + } + } + + return false; +} + bool validate_face(const LLVolumeFace& face) { for (U32 i = 0; i < face.mNumIndices; ++i) @@ -188,6 +263,31 @@ bool validate_face(const LLVolumeFace& face) } } + if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0) + { + llwarns << "Face has invalid number of indices." << llendl; + return false; + } + + /*const LLVector4a scale(0.5f); + + for (U32 i = 0; i < face.mNumIndices; i+=3) + { + U16 idx1 = face.mIndices[i]; + U16 idx2 = face.mIndices[i+1]; + U16 idx3 = face.mIndices[i+2]; + + LLVector4a v1; v1.setMul(face.mPositions[idx1], scale); + LLVector4a v2; v2.setMul(face.mPositions[idx2], scale); + LLVector4a v3; v3.setMul(face.mPositions[idx3], scale); + + if (ll_is_degenerate(v1,v2,v3)) + { + llwarns << "Degenerate face found!" << llendl; + return false; + } + }*/ + return true; } @@ -313,15 +413,17 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); childSetCommitCallback("lod_file_or_limit", refresh, this); - childSetCommitCallback("physics_load_radio", refresh, this); + childSetCommitCallback("physics_load_radio", onPhysicsLoadRadioCommit, this); //childSetCommitCallback("physics_optimize", refresh, this); //childSetCommitCallback("physics_use_hull", refresh, this); childDisable("upload_skin"); childDisable("upload_joints"); - + childDisable("ok_btn"); + childSetCommitCallback("confirm_checkbox", refresh, this); + mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn"); mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2)); @@ -381,12 +483,6 @@ LLFloaterModelPreview::~LLFloaterModelPreview() { sInstance = NULL; - if ( mModelPreview && mModelPreview->getResetJointFlag() ) - { - gAgentAvatarp->resetJointPositions(); - } - - if ( mModelPreview ) { delete mModelPreview; @@ -475,6 +571,29 @@ void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata ) } //static +void LLFloaterModelPreview::onPhysicsLoadRadioCommit( LLUICtrl*, void *userdata) +{ + LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; + if (fmp) + { + if (fmp->childGetValue("physics_use_lod").asBoolean()) + { + onPhysicsUseLOD(NULL,NULL); + } + if (fmp->childGetValue("physics_load_from_file").asBoolean()) + { + + } + LLModelPreview *model_preview = fmp->mModelPreview; + if (model_preview) + { + model_preview->refresh(); + model_preview->updateStatusMessages(); + } + } +} + +//static void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata) { LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata; @@ -578,6 +697,11 @@ void LLFloaterModelPreview::draw() childSetTextArg("status", "[STATUS]", getString(LLModel::getStatusString(mModelPreview->getLoadState() - LLModelLoader::ERROR_PARSING))); } else + if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_PARSING ) + { + childSetTextArg("status", "[STATUS]", getString("status_parse_error")); + } + else { childSetTextArg("status", "[STATUS]", getString("status_idle")); } @@ -997,7 +1121,7 @@ LLModelLoader::LLModelLoader( std::string filename, S32 lod, LLModelPreview* pre std::deque<std::string>& jointsFromNodes ) : mJointList( jointMap ) , mJointsFromNode( jointsFromNodes ) -, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE) +, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE), mNumOfFetchingTextures(0) { mJointMap["mPelvis"] = "mPelvis"; mJointMap["mTorso"] = "mTorso"; @@ -1162,11 +1286,7 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& void LLModelLoader::run() { - if (!doLoadModel()) - { - mPreview = NULL; - } - + doLoadModel(); doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); } @@ -1230,6 +1350,23 @@ bool LLModelLoader::doLoadModel() return false; } + //Verify some basic properties of the dae + //1. Basic validity check on controller + U32 controllerCount = (int) db->getElementCount( NULL, "controller" ); + bool result = false; + for ( int i=0; i<controllerCount; ++i ) + { + domController* pController = NULL; + db->getElement( (daeElement**) &pController, i , NULL, "controller" ); + result = mPreview->verifyController( pController ); + if (!result) + { + setLoadState( ERROR_PARSING ); + return true; + } + } + + //get unit scale mTransform.setIdentity(); @@ -1280,7 +1417,7 @@ bool LLModelLoader::doLoadModel() if(model->getStatus() != LLModel::NO_ERRORS) { setLoadState(ERROR_PARSING + model->getStatus()) ; - return true ; //abort + return false; //abort } if (model.notNull() && validate_model(model)) @@ -1577,7 +1714,7 @@ bool LLModelLoader::doLoadModel() { //llinfos<<"joint "<<lookingForJoint.c_str()<<llendl; LLMatrix4 jointTransform = mJointList[lookingForJoint]; - LLJoint* pJoint = gAgentAvatarp->getJoint( lookingForJoint ); + LLJoint* pJoint = mPreview->getPreviewAvatar()->getJoint( lookingForJoint ); if ( pJoint ) { pJoint->storeCurrentXform( jointTransform.getTranslation() ); @@ -1639,7 +1776,7 @@ bool LLModelLoader::doLoadModel() { if (pos.getCount() <= j+2) { - llerrs << "WTF?" << llendl; + llerrs << "Invalid position array size." << llendl; } LLVector3 v(pos[j], pos[j+1], pos[j+2]); @@ -1764,11 +1901,19 @@ bool LLModelLoader::doLoadModel() { llwarns << "document has no visual_scene" << llendl; setLoadState( ERROR_PARSING ); - return false; + return true; } + setLoadState( DONE ); - processElement(scene); + bool badElement = false; + + processElement( scene, badElement ); + + if ( badElement ) + { + setLoadState( ERROR_PARSING ); + } return true; } @@ -2129,7 +2274,8 @@ void LLModelLoader::loadTextures() iter->second[i].mMaterial[j].mDiffuseMap = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + iter->second[i].mMaterial[j].mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW); iter->second[i].mMaterial[j].mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE); - iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(); + iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(0, F32_MAX); + mNumOfFetchingTextures++ ; } } } @@ -2158,6 +2304,90 @@ bool LLModelLoader::isNodeAJoint( domNode* pNode ) return false; } +//----------------------------------------------------------------------------- +// verifyCount +//----------------------------------------------------------------------------- +bool LLModelPreview::verifyCount( int expected, int result ) +{ + if ( expected != result ) + { + llinfos<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<llendl; + return false; + } + return true; +} +//----------------------------------------------------------------------------- +// verifyController +//----------------------------------------------------------------------------- +bool LLModelPreview::verifyController( domController* pController ) +{ + + bool result = true; + + domSkin* pSkin = pController->getSkin(); + + if ( pSkin ) + { + xsAnyURI & uri = pSkin->getSource(); + domElement* pElement = uri.getElement(); + + if ( !pElement ) + { + llinfos<<"Can't resolve skin source"<<llendl; + return false; + } + + daeString type_str = pElement->getTypeName(); + if ( stricmp(type_str, "geometry") == 0 ) + { + //Skin is reference directly by geometry and get the vertex count from skin + domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights(); + U32 vertexWeightsCount = pVertexWeights->getCount(); + domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement(); + domMesh* pMesh = pGeometry->getMesh(); + + if ( pMesh ) + { + //Get vertex count from geometry + domVertices* pVertices = pMesh->getVertices(); + if ( !pVertices ) + { + llinfos<<"No vertices!"<<llendl; + return false; + } + + if ( pVertices ) + { + xsAnyURI src = pVertices->getInput_array()[0]->getSource(); + domSource* pSource = (domSource*) (domElement*) src.getElement(); + U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount(); + result = verifyCount( verticesCount, vertexWeightsCount ); + if ( !result ) + { + return result; + } + } + } + + U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount(); + result = verifyCount( vcountCount, vertexWeightsCount ); + if ( !result ) + { + return result; + } + + domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array(); + U32 sum = 0; + for (size_t i=0; i<vcountCount; i++) + { + sum += pVertexWeights->getVcount()->getValue()[i]; + } + result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() ); + } + } + + return result; +} //----------------------------------------------------------------------------- // extractTranslation() @@ -2268,7 +2498,7 @@ daeElement* LLModelLoader::getChildFromElement( daeElement* pElement, std::strin return NULL; } -void LLModelLoader::processElement(daeElement* element) +void LLModelLoader::processElement( daeElement* element, bool& badElement ) { LLMatrix4 saved_transform = mTransform; @@ -2301,8 +2531,11 @@ void LLModelLoader::processElement(daeElement* element) { domFloat3 dom_value = scale->getValue(); + + LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]); + scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes LLMatrix4 scaling; - scaling.initScale(LLVector3(dom_value[0], dom_value[1], dom_value[2])); + scaling.initScale(scale_vector); scaling *= mTransform; mTransform = scaling; @@ -2365,6 +2598,12 @@ void LLModelLoader::processElement(daeElement* element) } } } + else + { + llinfos<<"Unable to resolve geometry URL."<<llendl; + badElement = true; + } + } domInstance_node* instance_node = daeSafeCast<domInstance_node>(element); @@ -2373,7 +2612,7 @@ void LLModelLoader::processElement(daeElement* element) daeElement* instance = instance_node->getUrl().getElement(); if (instance) { - processElement(instance); + processElement(instance,badElement); } } @@ -2381,7 +2620,7 @@ void LLModelLoader::processElement(daeElement* element) daeTArray< daeSmartRef<daeElement> > children = element->getChildren(); for (S32 i = 0; i < children.getCount(); i++) { - processElement(children[i]); + processElement(children[i],badElement); } domNode* node = daeSafeCast<domNode>(element); @@ -2597,6 +2836,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) mLoading = false; mLoadState = LLModelLoader::STARTING; mGroup = 0; + mLODFrozen = false; mBuildShareTolerance = 0.f; mBuildQueueMode = GLOD_QUEUE_GREEDY; mBuildBorderMode = GLOD_BORDER_UNLOCK; @@ -2605,6 +2845,13 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) for (U32 i = 0; i < LLModel::NUM_LODS; ++i) { mRequestedTriangleCount[i] = 0; + mRequestedCreaseAngle[i] = -1.f; + mRequestedLoDMode[i] = 0; + mRequestedErrorThreshold[i] = 0.f; + mRequestedBuildOperator[i] = 0; + mRequestedQueueMode[i] = 0; + mRequestedBorderMode[i] = 0; + mRequestedShareTolerance[i] = 0.f; } mViewOption["show_textures"] = false; @@ -2649,13 +2896,15 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) mMasterLegacyJointList.push_front("mHipLeft"); mMasterLegacyJointList.push_front("mKneeLeft"); mMasterLegacyJointList.push_front("mFootLeft"); + + createPreviewAvatar(); } LLModelPreview::~LLModelPreview() { if (mModelLoader) { - delete mModelLoader; + mModelLoader->mPreview = NULL; mModelLoader = NULL; } //*HACK : *TODO : turn this back on when we understand why this crashes @@ -2670,7 +2919,8 @@ U32 LLModelPreview::calcResourceCost() if (mFMP && mModelLoader) { - if ( getLoadState() < LLModelLoader::ERROR_PARSING ) + const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); + if ( getLoadState() < LLModelLoader::ERROR_PARSING && confirmed_checkbox ) { mFMP->childEnable("ok_btn"); } @@ -2702,7 +2952,7 @@ U32 LLModelPreview::calcResourceCost() if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() ) { - gAgentAvatarp->setPelvisOffset( mPelvisZOffset ); + getPreviewAvatar()->setPelvisOffset( mPelvisZOffset ); } F32 streaming_cost = 0.f; @@ -2812,7 +3062,8 @@ void LLModelPreview::rebuildUploadData() F32 max_scale = 0.f; - if ( mBaseScene.size() > 0 ) + const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); + if ( mBaseScene.size() > 0 && confirmed_checkbox ) { mFMP->childEnable("ok_btn"); } @@ -3216,6 +3467,8 @@ void LLModelPreview::loadModelCallback(S32 lod) } mLoading = false; + if (mFMP) + mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE); refresh(); mModelLoadedSignal(); @@ -3229,7 +3482,7 @@ void LLModelPreview::resetPreviewTarget() mPreviewScale = (mModelLoader->mExtents[1] - mModelLoader->mExtents[0]) * 0.5f; } - setPreviewTarget(mPreviewScale.magVec()*2.f); + setPreviewTarget(mPreviewScale.magVec()*10.f); } void LLModelPreview::generateNormals() @@ -3247,6 +3500,8 @@ void LLModelPreview::generateNormals() F32 angle_cutoff = mFMP->childGetValue("crease_angle").asReal(); + mRequestedCreaseAngle[which_lod] = angle_cutoff; + angle_cutoff *= DEG_TO_RAD; if (which_lod == 3 && !mBaseModel.empty()) @@ -3266,7 +3521,7 @@ void LLModelPreview::generateNormals() mVertexBuffer[which_lod].clear(); refresh(); - + updateStatusMessages(); } void LLModelPreview::clearMaterials() @@ -3342,6 +3597,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim { lod_mode = iface->getFirstSelectedIndex(); } + mRequestedLoDMode[mPreviewLOD] = lod_mode; F32 lod_error_threshold = mFMP->childGetValue("lod_error_threshold").asReal(); @@ -3365,6 +3621,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim { build_operator = iface->getFirstSelectedIndex(); } + mRequestedBuildOperator[mPreviewLOD] = build_operator; if (build_operator == 0) { @@ -3381,6 +3638,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim { queue_mode = iface->getFirstSelectedIndex(); } + mRequestedQueueMode[mPreviewLOD] = queue_mode; if (queue_mode == 0) { @@ -3402,6 +3660,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim { border_mode = iface->getFirstSelectedIndex(); } + mRequestedBorderMode[mPreviewLOD] = border_mode; if (border_mode == 0) { @@ -3437,6 +3696,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim mBuildShareTolerance = share_tolerance; object_dirty = true; } + mRequestedShareTolerance[mPreviewLOD] = share_tolerance; if (mGroup == 0) { @@ -3545,6 +3805,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 submeshes = 0; mRequestedTriangleCount[lod] = triangle_count; + mRequestedErrorThreshold[lod] = lod_error_threshold; glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode); stop_gloderror(); @@ -3739,7 +4000,35 @@ void LLModelPreview::updateStatusMessages() mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH]; } + bool has_degenerate = false; + {//check for degenerate triangles in physics mesh + U32 lod = LLModel::LOD_PHYSICS; + const LLVector4a scale(0.5f); + for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i) + { //for each model in the lod + if (mModel[lod][i]->mPhysics.mHull.empty()) + { //no decomp exists + S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces(); + for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j) + { //for each submesh (face), add triangles and vertices to current total + const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j); + for (S32 k = 0; k < face.mNumIndices && !has_degenerate; ) + { + LLVector4a v1; v1.setMul(face.mPositions[face.mIndices[k++]], scale); + LLVector4a v2; v2.setMul(face.mPositions[face.mIndices[k++]], scale); + LLVector4a v3; v3.setMul(face.mPositions[face.mIndices[k++]], scale); + + if (ll_is_degenerate(v1,v2,v3)) + { + has_degenerate = true; + } + } + } + } + } + } + mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH])); std::string mesh_status_na = mFMP->getString("mesh_status_na"); @@ -3832,6 +4121,21 @@ void LLModelPreview::updateStatusMessages() } } + + //make sure no hulls have more than 256 points in them + for (U32 i = 0; upload_ok && i < mModel[LLModel::LOD_PHYSICS].size(); ++i) + { + LLModel* mdl = mModel[LLModel::LOD_PHYSICS][i]; + + for (U32 j = 0; upload_ok && j < mdl->mPhysics.mHull.size(); ++j) + { + if (mdl->mPhysics.mHull[j].size() > 256) + { + upload_ok = false; + } + } + } + bool errorStateFromLoader = getLoadState() >= LLModelLoader::ERROR_PARSING ? true : false; bool skinAndRigOk = true; @@ -3851,10 +4155,23 @@ void LLModelPreview::updateStatusMessages() } } - if ( upload_ok && !errorStateFromLoader && skinAndRigOk ) + if(upload_ok && mModelLoader) + { + if(!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean()) + { + upload_ok = false ; + } + } + + const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); + if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate && confirmed_checkbox) { mFMP->childEnable("ok_btn"); } + else + { + mFMP->childDisable("ok_btn"); + } //add up physics triangles etc S32 start = 0; @@ -4021,6 +4338,9 @@ void LLModelPreview::updateStatusMessages() { // auto generate, also the default case for wizard which has no radio selection fmp->mLODMode[mPreviewLOD] = 1; + //don't actually regenerate lod when refreshing UI + mLODFrozen = true; + for (U32 i = 0; i < num_file_controls; ++i) { mFMP->childDisable(file_controls[i]); @@ -4033,20 +4353,21 @@ void LLModelPreview::updateStatusMessages() //if (threshold) { - U32 lod_mode = 0; - LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode"); - if (iface) - { - lod_mode = iface->getFirstSelectedIndex(); - } - LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold"); LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit"); limit->setMaxValue(mMaxTriangleLimit); - limit->setValue(mRequestedTriangleCount[mPreviewLOD]); + limit->forceSetValue(mRequestedTriangleCount[mPreviewLOD]); + + threshold->forceSetValue(mRequestedErrorThreshold[mPreviewLOD]); - if (lod_mode == 0) + mFMP->getChild<LLComboBox>("lod_mode")->selectNthItem(mRequestedLoDMode[mPreviewLOD]); + mFMP->getChild<LLComboBox>("build_operator")->selectNthItem(mRequestedBuildOperator[mPreviewLOD]); + mFMP->getChild<LLComboBox>("queue_mode")->selectNthItem(mRequestedQueueMode[mPreviewLOD]); + mFMP->getChild<LLComboBox>("border_mode")->selectNthItem(mRequestedBorderMode[mPreviewLOD]); + mFMP->getChild<LLSpinCtrl>("share_tolerance")->setValue(mRequestedShareTolerance[mPreviewLOD]); + + if (mRequestedLoDMode[mPreviewLOD] == 0) { limit->setVisible(true); threshold->setVisible(false); @@ -4060,6 +4381,8 @@ void LLModelPreview::updateStatusMessages() threshold->setVisible(true); } } + + mLODFrozen = false; } } @@ -4075,6 +4398,20 @@ void LLModelPreview::updateStatusMessages() mFMP->childDisable("physics_file"); mFMP->childDisable("physics_browse"); } + + LLSpinCtrl* crease = mFMP->getChild<LLSpinCtrl>("crease_angle"); + + if (mRequestedCreaseAngle[mPreviewLOD] == -1.f) + { + mFMP->childSetColor("crease_label", LLColor4::grey); + crease->forceSetValue(75.f); + } + else + { + mFMP->childSetColor("crease_label", LLColor4::white); + crease->forceSetValue(mRequestedCreaseAngle[mPreviewLOD]); + } + } void LLModelPreview::setPreviewTarget(F32 distance) @@ -4189,11 +4526,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); LLVector4 w(0,0,0,0); - if (weight_list.size() > 4) - { - llerrs << "WTF?" << llendl; - } - + for (U32 i = 0; i < weight_list.size(); ++i) { F32 wght = llmin(weight_list[i].mWeight, 0.999999f); @@ -4241,42 +4574,6 @@ void LLModelPreview::update() } //----------------------------------------------------------------------------- -// changeAvatarsJointPositions() -//----------------------------------------------------------------------------- -void LLModelPreview::changeAvatarsJointPositions( LLModel* pModel ) -{ - if ( mMasterJointList.empty() ) - { - return; - } - - std::vector<std::string> :: const_iterator jointListItBegin = pModel->mSkinInfo.mJointNames.begin(); - std::vector<std::string> :: const_iterator jointListItEnd = pModel->mSkinInfo.mJointNames.end(); - - S32 index = 0; - for ( ; jointListItBegin!=jointListItEnd; ++jointListItBegin, ++index ) - { - std::string elem = *jointListItBegin; - //llinfos<<"joint "<<elem<<llendl; - - S32 matrixCnt = pModel->mSkinInfo.mAlternateBindMatrix.size(); - if ( matrixCnt < 1 ) - { - llinfos<<"Total WTF moment :"<<matrixCnt<<llendl; - } - else - { - LLMatrix4 jointTransform = pModel->mSkinInfo.mAlternateBindMatrix[index]; - - LLJoint* pJoint = gAgentAvatarp->getJoint( elem ); - if ( pJoint ) - { - pJoint->storeCurrentXform( jointTransform.getTranslation() ); - } - } - } -} -//----------------------------------------------------------------------------- // getTranslationForJointOffset() //----------------------------------------------------------------------------- LLVector3 LLModelPreview::getTranslationForJointOffset( std::string joint ) @@ -4290,6 +4587,30 @@ LLVector3 LLModelPreview::getTranslationForJointOffset( std::string joint ) return LLVector3(0.0f,0.0f,0.0f); } //----------------------------------------------------------------------------- +// createPreviewAvatar +//----------------------------------------------------------------------------- +void LLModelPreview::createPreviewAvatar( void ) +{ + mPreviewAvatar = (LLVOAvatar*)gObjectList.createObjectViewer( LL_PCODE_LEGACY_AVATAR, gAgent.getRegion() ); + if ( mPreviewAvatar ) + { + mPreviewAvatar->createDrawable( &gPipeline ); + mPreviewAvatar->mIsDummy = TRUE; + mPreviewAvatar->mSpecialRenderMode = 1; + mPreviewAvatar->setPositionAgent( LLVector3::zero ); + mPreviewAvatar->slamPosition(); + mPreviewAvatar->updateJointLODs(); + mPreviewAvatar->updateGeometry( mPreviewAvatar->mDrawable ); + mPreviewAvatar->startMotion( ANIM_AGENT_STAND ); + mPreviewAvatar->hideSkirt(); + } + else + { + llinfos<<"Failed to create preview avatar for upload model window"<<llendl; + } +} + +//----------------------------------------------------------------------------- // render() //----------------------------------------------------------------------------- BOOL LLModelPreview::render() @@ -4403,25 +4724,6 @@ BOOL LLModelPreview::render() mFMP->childSetEnabled("upload_joints", upload_skin); - //poke at avatar when we upload custom joints - /* - if ( upload_joints ) - { - for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) - { - for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) - { - LLModelInstance& instance = *model_iter; - LLModel* model = instance.mModel; - if ( !model->mSkinWeights.empty() ) - { - changeAvatarsJointPositions( model ); - } - } - } - } - */ - F32 explode = mFMP->childGetValue("physics_explode").asReal(); glClear(GL_DEPTH_BUFFER_BIT); @@ -4437,11 +4739,11 @@ BOOL LLModelPreview::render() LLVector3 target_pos = mPreviewTarget+offset; F32 z_near = 0.001f; - F32 z_far = mCameraDistance+mPreviewScale.magVec()+mCameraOffset.magVec(); + F32 z_far = mCameraDistance*10.0f+mPreviewScale.magVec()+mCameraOffset.magVec(); if (skin_weight) { - target_pos = gAgentAvatarp->getPositionAgent(); + target_pos = getPreviewAvatar()->getPositionAgent(); z_near = 0.01f; z_far = 1024.f; mCameraDistance = 16.f; @@ -4587,39 +4889,43 @@ BOOL LLModelPreview::render() LLModel::Decomposition& physics = model->mPhysics; - if (physics.mMesh.empty()) - { //build vertex buffer for physics mesh - gMeshRepo.buildPhysicsMesh(physics); - } - - if (!physics.mMesh.empty()) - { //render hull instead of mesh + if (!physics.mHull.empty()) + { render_mesh = false; - for (U32 i = 0; i < physics.mMesh.size(); ++i) - { - if (explode > 0.f) + + if (physics.mMesh.empty()) + { //build vertex buffer for physics mesh + gMeshRepo.buildPhysicsMesh(physics); + } + + if (!physics.mMesh.empty()) + { //render hull instead of mesh + for (U32 i = 0; i < physics.mMesh.size(); ++i) { - gGL.pushMatrix(); + if (explode > 0.f) + { + gGL.pushMatrix(); - LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters; - offset *= explode; + LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters; + offset *= explode; - gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); - } + gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); + } - static std::vector<LLColor4U> hull_colors; + static std::vector<LLColor4U> hull_colors; - if (i+1 >= hull_colors.size()) - { - hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255)); - } + if (i+1 >= hull_colors.size()) + { + hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255)); + } - glColor4ubv(hull_colors[i].mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); + glColor4ubv(hull_colors[i].mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); - if (explode > 0.f) - { - gGL.popMatrix(); + if (explode > 0.f) + { + gGL.popMatrix(); + } } } } @@ -4645,9 +4951,10 @@ BOOL LLModelPreview::render() glColor3f(1.f, 1.f, 0.f); - glLineWidth(3.f); + glLineWidth(2.f); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1.f); } @@ -4656,13 +4963,86 @@ BOOL LLModelPreview::render() gGL.popMatrix(); } + glLineWidth(3.f); + glPointSize(8.f); + gPipeline.enableLightsFullbright(LLColor4::white); + //show degenerate triangles + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + LLGLDisable cull(GL_CULL_FACE); + glColor4f(1.f,0.f,0.f,1.f); + const LLVector4a scale(0.5f); + + for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + { + LLModelInstance& instance = *iter; + + LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS]; + + if (!model) + { + continue; + } + + gGL.pushMatrix(); + LLMatrix4 mat = instance.mTransform; + + glMultMatrixf((GLfloat*) mat.mMatrix); + + + LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; + if (decomp) + { + LLMutexLock(decomp->mMutex); + + LLModel::Decomposition& physics = model->mPhysics; + + if (physics.mHull.empty()) + { + if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) + { + genBuffers(LLModel::LOD_PHYSICS, false); + } + + for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i) + { + LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; + + buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + + LLStrider<LLVector3> pos_strider; + buffer->getVertexStrider(pos_strider, 0); + LLVector4a* pos = (LLVector4a*) pos_strider.get(); + + LLStrider<U16> idx; + buffer->getIndexStrider(idx, 0); + + for (U32 i = 0; i < buffer->getNumIndices(); i += 3) + { + LLVector4a v1; v1.setMul(pos[*idx++], scale); + LLVector4a v2; v2.setMul(pos[*idx++], scale); + LLVector4a v3; v3.setMul(pos[*idx++], scale); + + if (ll_is_degenerate(v1,v2,v3)) + { + buffer->draw(LLRender::LINE_LOOP, 3, i); + buffer->draw(LLRender::POINTS, 3, i); + } + } + } + } + } + + gGL.popMatrix(); + } + glLineWidth(1.f); + glPointSize(1.f); + gPipeline.enableLightsPreview(); gGL.setSceneBlendType(LLRender::BT_ALPHA); } } else { - LLVOAvatarSelf* avatar = gAgentAvatarp; - target_pos = avatar->getPositionAgent(); + target_pos = getPreviewAvatar()->getPositionAgent(); LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera @@ -4671,7 +5051,7 @@ BOOL LLModelPreview::render() if (joint_positions) { - avatar->renderCollisionVolumes(); + getPreviewAvatar()->renderCollisionVolumes(); } for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) @@ -4702,7 +5082,7 @@ BOOL LLModelPreview::render() LLMatrix4 mat[64]; for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j) { - LLJoint* joint = avatar->getJoint(model->mSkinInfo.mJointNames[j]); + LLJoint* joint = getPreviewAvatar()->getJoint(model->mSkinInfo.mJointNames[j]); if (joint) { mat[j] = model->mSkinInfo.mInvBindMatrix[j]; @@ -4921,13 +5301,24 @@ void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture { LLModelPreview* preview = (LLModelPreview*) userdata; preview->refresh(); + + if(final && preview->mModelLoader) + { + if(preview->mModelLoader->mNumOfFetchingTextures > 0) + { + preview->mModelLoader->mNumOfFetchingTextures-- ; + } + } } void LLModelPreview::onLODParamCommit(bool enforce_tri_limit) { - genLODs(mPreviewLOD, 3, enforce_tri_limit); - updateStatusMessages(); - refresh(); + if (!mLODFrozen) + { + genLODs(mPreviewLOD, 3, enforce_tri_limit); + updateStatusMessages(); + refresh(); + } } LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl) @@ -4939,35 +5330,7 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL mParams = sInstance->mDecompParams; //copy out positions and indices - if (mdl) - { - U16 index_offset = 0; - - mPositions.clear(); - mIndices.clear(); - - //queue up vertex positions and indices - for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = mdl->getVolumeFace(i); - if (mPositions.size() + face.mNumVertices > 65535) - { - continue; - } - - for (U32 j = 0; j < face.mNumVertices; ++j) - { - mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); - } - - for (U32 j = 0; j < face.mNumIndices; ++j) - { - mIndices.push_back(face.mIndices[j]+index_offset); - } - - index_offset += face.mNumVertices; - } - } + assignData(mdl) ; } void LLFloaterModelPreview::setStatusMessage(const std::string& msg) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 4d8b46807f..d4f6b4d293 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -50,6 +50,7 @@ class domProfile_COMMON; class domInstance_geometry; class domNode; class domTranslate; +class domController; class LLMenuButton; class LLToggleableMenu; @@ -107,7 +108,7 @@ public: void loadModelCallback(); void loadTextures() ; //called in the main thread. - void processElement(daeElement* element); + void processElement(daeElement* element, bool& badElement); std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo); LLImportMaterial profileToMaterial(domProfile_COMMON* material); std::string getElementLabel(daeElement *element); @@ -131,6 +132,9 @@ public: JointTransformMap& mJointList; std::deque<std::string>& mJointsFromNode; + S32 mNumOfFetchingTextures ; //updated in the main thread + bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread. + private: static std::list<LLModelLoader*> sActiveLoaderList; static bool isAlive(LLModelLoader* loader) ; @@ -199,6 +203,8 @@ protected: static void onUploadJointsCommit(LLUICtrl*,void*); static void onUploadSkinCommit(LLUICtrl*,void*); + static void onPhysicsLoadRadioCommit(LLUICtrl*,void *data); + static void onPreviewLODCommit(LLUICtrl*,void*); static void onGenerateNormalsCommit(LLUICtrl*,void*); @@ -309,9 +315,6 @@ public: void setHasPivot( bool val ) { mHasPivot = val; } void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; } - //Sets the current avatars joints to new positions - //Makes in world go to shit, however - void changeAvatarsJointPositions( LLModel* pModel ); //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); void critiqueJointToNodeMappingFromScene( void ); @@ -325,6 +328,8 @@ public: //Accessors for the legacy rigs const bool isLegacyRigValid( void ) const { return mLegacyRigValid; } void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; } + //Verify that a controller matches vertex counts + bool verifyController( domController* pController ); static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); @@ -341,6 +346,14 @@ public: LLVector3 getTranslationForJointOffset( std::string joint ); +private: + //Utility function for controller vertex compare + bool verifyCount( int expected, int result ); + //Creates the dummy avatar for the preview window + void createPreviewAvatar( void ); + //Accessor for the dummy avatar + LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; } + protected: friend class LLModelLoader; friend class LLFloaterModelPreview; @@ -373,13 +386,20 @@ public: std::map<std::string, bool> mViewOption; //GLOD object parameters (must rebuild object if these change) + bool mLODFrozen; F32 mBuildShareTolerance; U32 mBuildQueueMode; U32 mBuildOperator; U32 mBuildBorderMode; + U32 mRequestedLoDMode[LLModel::NUM_LODS]; S32 mRequestedTriangleCount[LLModel::NUM_LODS]; + F32 mRequestedErrorThreshold[LLModel::NUM_LODS]; + U32 mRequestedBuildOperator[LLModel::NUM_LODS]; + U32 mRequestedQueueMode[LLModel::NUM_LODS]; + U32 mRequestedBorderMode[LLModel::NUM_LODS]; + F32 mRequestedShareTolerance[LLModel::NUM_LODS]; + F32 mRequestedCreaseAngle[LLModel::NUM_LODS]; - LLModelLoader* mModelLoader; LLModelLoader::scene mScene[LLModel::NUM_LODS]; @@ -415,6 +435,7 @@ public: std::deque<std::string> mMasterLegacyJointList; std::deque<std::string> mJointsFromNode; JointTransformMap mJointTransformMap; + LLPointer<LLVOAvatar> mPreviewAvatar; }; #endif // LL_LLFLOATERMODELPREVIEW_H diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp index faf81dbc5c..707c8288df 100644 --- a/indra/newview/llfloatermodelwizard.cpp +++ b/indra/newview/llfloatermodelwizard.cpp @@ -422,8 +422,11 @@ void LLFloaterModelWizard::executePhysicsStage(std::string stage_name) { LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i]; DecompRequest* request = new DecompRequest(stage_name, mdl); - sInstance->mCurRequest.insert(request); - gMeshRepo.mDecompThread->submitRequest(request); + if(request->isValid()) + { + sInstance->mCurRequest.insert(request); + gMeshRepo.mDecompThread->submitRequest(request); + } } } } @@ -438,35 +441,7 @@ LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLM mParams = sInstance->mDecompParams; //copy out positions and indices - if (mdl) - { - U16 index_offset = 0; - - mPositions.clear(); - mIndices.clear(); - - //queue up vertex positions and indices - for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = mdl->getVolumeFace(i); - if (mPositions.size() + face.mNumVertices > 65535) - { - continue; - } - - for (U32 j = 0; j < face.mNumVertices; ++j) - { - mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); - } - - for (U32 j = 0; j < face.mNumIndices; ++j) - { - mIndices.push_back(face.mIndices[j]+index_offset); - } - - index_offset += face.mNumVertices; - } - } + assignData(mdl) ; } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 4b15695cbf..7848484ac6 100644..100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -187,12 +187,26 @@ void LLVoiceSetKeyDialog::onCancel(void* user_data) void handleNameTagOptionChanged(const LLSD& newvalue); void handleDisplayNamesOptionChanged(const LLSD& newvalue); bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response); +bool callback_clear_cache(const LLSD& notification, const LLSD& response); //bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater); //bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater); void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator); +bool callback_clear_cache(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if ( option == 0 ) // YES + { + // flag client texture cache for clearing next time the client runs + gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE); + LLNotificationsUtil::add("CacheWillClear"); + } + + return false; +} + bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -305,7 +319,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreference::onBtnCancel, this)); mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreference::onBtnOK, this)); -// mCommitCallbackRegistrar.add("Pref.ClearCache", boost::bind(&LLFloaterPreference::onClickClearCache, this)); + mCommitCallbackRegistrar.add("Pref.ClearCache", boost::bind(&LLFloaterPreference::onClickClearCache, this)); mCommitCallbackRegistrar.add("Pref.WebClearCache", boost::bind(&LLFloaterPreference::onClickBrowserClearCache, this)); mCommitCallbackRegistrar.add("Pref.SetCache", boost::bind(&LLFloaterPreference::onClickSetCache, this)); mCommitCallbackRegistrar.add("Pref.ResetCache", boost::bind(&LLFloaterPreference::onClickResetCache, this)); @@ -313,6 +327,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.SelectSkin", boost::bind(&LLFloaterPreference::onSelectSkin, this)); mCommitCallbackRegistrar.add("Pref.VoiceSetKey", boost::bind(&LLFloaterPreference::onClickSetKey, this)); mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse", boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this)); + mCommitCallbackRegistrar.add("Pref.SetSounds", boost::bind(&LLFloaterPreference::onClickSetSounds, this)); // mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs", boost::bind(&LLFloaterPreference::onClickSkipDialogs, this)); // mCommitCallbackRegistrar.add("Pref.ClickResetDialogs", boost::bind(&LLFloaterPreference::onClickResetDialogs, this)); mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this)); @@ -809,6 +824,11 @@ void LLFloaterPreference::refreshEnabledGraphics() } } +void LLFloaterPreference::onClickClearCache() +{ + LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache); +} + void LLFloaterPreference::onClickBrowserClearCache() { LLNotificationsUtil::add("ConfirmClearBrowserCache", LLSD(), LLSD(), callback_clear_browser_cache); @@ -868,14 +888,15 @@ void LLFloaterPreference::onClickSetCache() void LLFloaterPreference::onClickResetCache() { - if (!gSavedSettings.getString("CacheLocation").empty()) + if (gDirUtilp->getCacheDir(false) == gDirUtilp->getCacheDir(true)) { - gSavedSettings.setString("NewCacheLocation", ""); - gSavedSettings.setString("NewCacheLocationTopFolder", ""); + // The cache location was already the default. + return; } - + gSavedSettings.setString("NewCacheLocation", ""); + gSavedSettings.setString("NewCacheLocationTopFolder", ""); LLNotificationsUtil::add("CacheWillBeMoved"); - std::string cache_location = gDirUtilp->getCacheDir(true); + std::string cache_location = gDirUtilp->getCacheDir(false); gSavedSettings.setString("CacheLocation", cache_location); std::string top_folder(gDirUtilp->getBaseFileName(cache_location)); gSavedSettings.setString("CacheLocationTopFolder", top_folder); @@ -1266,6 +1287,14 @@ void LLFloaterPreference::onClickSetMiddleMouse() p2t_line_editor->setValue(advanced_preferences->getString("middle_mouse")); } } + +void LLFloaterPreference::onClickSetSounds() +{ + // Disable Enable gesture sounds checkbox if the master sound is disabled + // or if sound effects are disabled. + getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds")); +} + /* void LLFloaterPreference::onClickSkipDialogs() { diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 5fe509fb37..61f2c78640 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -88,7 +88,8 @@ protected: void onBtnCancel(); void onBtnApply(); - void onClickBrowserClearCache(); + void onClickClearCache(); // Clear viewer texture cache, vfs, and VO cache on next startup + void onClickBrowserClearCache(); // Clear web history and caches as well as viewer caches above void onLanguageChange(); void onNameTagOpacityChange(const LLSD& newvalue); @@ -99,7 +100,7 @@ protected: void onChangeCustom(); void updateMeterText(LLUICtrl* ctrl); void onOpenHardwareSettings(); - /// callback for defaults + // callback for defaults void setHardwareDefaults(); // callback for when client turns on shaders void onVertexShaderEnable(); @@ -128,6 +129,7 @@ public: void onClickSetKey(); void setKey(KEY key); void onClickSetMiddleMouse(); + void onClickSetSounds(); // void onClickSkipDialogs(); // void onClickResetDialogs(); void onClickEnablePopup(); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 34fda49375..6b3e3088d5 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -82,6 +82,7 @@ #include "llvlcomposition.h" #include "lltrans.h" #include "llagentui.h" +#include "llmeshrepository.h" const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; @@ -590,6 +591,9 @@ bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region) getChildView("im_btn")->setEnabled(allow_modify); getChildView("manage_telehub_btn")->setEnabled(allow_modify); + const bool enable_mesh = gMeshRepo.meshRezEnabled(); + getChildView("mesh_rez_enabled_check")->setVisible(enable_mesh); + getChildView("mesh_rez_enabled_check")->setEnabled(getChildView("mesh_rez_enabled_check")->getEnabled() && enable_mesh); // Data gets filled in by processRegionInfo return LLPanelRegionInfo::refreshFromRegion(region); diff --git a/indra/newview/llfloatersounddevices.cpp b/indra/newview/llfloatersounddevices.cpp index 9fe7c7f9dd..e692f1735a 100644 --- a/indra/newview/llfloatersounddevices.cpp +++ b/indra/newview/llfloatersounddevices.cpp @@ -68,6 +68,9 @@ BOOL LLFloaterSoundDevices::postBuild() if (panel) { panel->setUseTuningMode(false); + getChild<LLUICtrl>("voice_input_device")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel)); + getChild<LLUICtrl>("voice_output_device")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel)); + getChild<LLUICtrl>("mic_volume_slider")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel)); } return TRUE; } diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 73c1f99fa0..0d798afdcc 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -85,6 +85,8 @@ #include "llviewerwindow.h" #include "llvovolume.h" #include "lluictrlfactory.h" +#include "llaccountingquotamanager.h" +#include "llmeshrepository.h" // Globals LLFloaterTools *gFloaterTools = NULL; @@ -422,7 +424,8 @@ void LLFloaterTools::refresh() // Refresh object and prim count labels LLLocale locale(LLLocale::USER_LOCALE); - if ((gAgent.getRegion() && gAgent.getRegion()->getCapability("GetMesh").empty()) || !gSavedSettings.getBOOL("MeshEnabled")) +#if 0 + if (gMeshRepo.meshRezEnabled()) { std::string obj_count_string; LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); @@ -446,6 +449,7 @@ void LLFloaterTools::refresh() getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); } else +#endif { // Get the number of objects selected std::string root_object_count_string; @@ -787,9 +791,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) getChildView("Strength:")->setVisible( land_visible); } - bool show_mesh_cost = gAgent.getRegion() && - !gAgent.getRegion()->getCapability("GetMesh").empty() && - gSavedSettings.getBOOL("MeshEnabled"); + bool show_mesh_cost = gMeshRepo.meshRezEnabled(); getChildView("obj_count")->setVisible( !land_visible && !show_mesh_cost); getChildView("prim_count")->setVisible( !land_visible && !show_mesh_cost); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index f8a4ce7ad0..f8a4ce7ad0 100644..100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp diff --git a/indra/newview/llgesturelistener.cpp b/indra/newview/llgesturelistener.cpp new file mode 100644 index 0000000000..2fff506681 --- /dev/null +++ b/indra/newview/llgesturelistener.cpp @@ -0,0 +1,159 @@ +/** + * @file llgesturelistener.cpp + * @author Dave Simmons + * @date 2011-03-28 + * @brief Implementation for LLGestureListener. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llgesturelistener.h" +#include "llgesturemgr.h" +#include "llmultigesture.h" + + +LLGestureListener::LLGestureListener() + : LLEventAPI("LLGesture", + "LLGesture listener interface to control gestures") +{ + add("getActiveGestures", + "Return information about the agent's available gestures [\"reply\"]:\n" + "[\"gestures\"]: a dictionary with UUID strings as keys\n" + " and the following dict values for each entry:\n" + " [\"name\"]: name of the gesture, may be empty\n" + " [\"trigger\"]: trigger string used to invoke via user chat, may be empty\n" + " [\"playing\"]: true or false indicating the playing state", + &LLGestureListener::getActiveGestures, + LLSDMap("reply", LLSD())); + add("isGesturePlaying", + "[\"id\"]: UUID of the gesture to query. Returns True or False in [\"playing\"] value of the result", + &LLGestureListener::isGesturePlaying); + add("startGesture", + "[\"id\"]: UUID of the gesture to start playing", + &LLGestureListener::startGesture); + add("stopGesture", + "[\"id\"]: UUID of the gesture to stop", + &LLGestureListener::stopGesture); +} + + +// "getActiveGestures" command +void LLGestureListener::getActiveGestures(const LLSD& event_data) const +{ + LLSD reply = LLSD::emptyMap(); + LLSD gesture_map = LLSD::emptyMap(); + + const LLGestureMgr::item_map_t& active_gestures = LLGestureMgr::instance().getActiveGestures(); + + // Scan active gesture map and get all the names + LLGestureMgr::item_map_t::const_iterator it; + for (it = active_gestures.begin(); it != active_gestures.end(); ++it) + { + LLMultiGesture* gesture = (*it).second; + if (gesture) + { // Add an entry to the result map with the LLUUID as key with a map containing data + LLSD info = LLSD::emptyMap(); + info["name"] = (LLSD::String) gesture->mName; + info["trigger"] = (LLSD::String) gesture->mTrigger; + info["playing"] = (LLSD::Boolean) gesture->mPlaying; + + gesture_map[(*it).first.asString()] = info; + } + } + + reply["gestures"] = gesture_map; + sendReply(reply, event_data); +} + + + +// "isGesturePlaying" command +void LLGestureListener::isGesturePlaying(const LLSD& event_data) const +{ + bool is_playing = false; + if (event_data.has("id")) + { + LLUUID gesture_id = event_data["id"].asUUID(); + if (gesture_id.notNull()) + { + is_playing = LLGestureMgr::instance().isGesturePlaying(gesture_id); + } + else + { + llwarns << "isGesturePlaying did not find a gesture object for " << gesture_id << llendl; + } + } + else + { + llwarns << "isGesturePlaying didn't have 'id' value passed in" << llendl; + } + + LLSD reply = LLSD::emptyMap(); + reply["playing"] = (LLSD::Boolean) is_playing; + sendReply(reply, event_data); +} + + +// "startGesture" command +void LLGestureListener::startGesture(LLSD const & event_data) const +{ + startOrStopGesture(event_data, true); +} + + +// "stopGesture" command +void LLGestureListener::stopGesture(LLSD const & event_data) const +{ + startOrStopGesture(event_data, false); +} + + +// Real code for "startGesture" or "stopGesture" +void LLGestureListener::startOrStopGesture(LLSD const & event_data, bool start) const +{ + if (event_data.has("id")) + { + LLUUID gesture_id = event_data["id"].asUUID(); + if (gesture_id.notNull()) + { + if (start) + { + LLGestureMgr::instance().playGesture(gesture_id); + } + else + { + LLGestureMgr::instance().stopGesture(gesture_id); + } + } + else + { + llwarns << "startOrStopGesture did not find a gesture object for " << gesture_id << llendl; + } + } + else + { + llwarns << "startOrStopGesture didn't have 'id' value passed in" << llendl; + } +} + diff --git a/indra/newview/llgesturelistener.h b/indra/newview/llgesturelistener.h new file mode 100644 index 0000000000..6f59698ed1 --- /dev/null +++ b/indra/newview/llgesturelistener.h @@ -0,0 +1,52 @@ +/** + * @file llgesturelistener.h + * @author Dave Simmons + * @date 2011-03-15 + * @brief Class definition for LLGestureListener. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#ifndef LL_LLGESTURELISTENER_H +#define LL_LLGESTURELISTENER_H + +#include "lleventapi.h" + +class LLSD; + +class LLGestureListener : public LLEventAPI +{ +public: + LLGestureListener(); + +private: + void getActiveGestures(LLSD const & gesture_data) const; + void isGesturePlaying(LLSD const & gesture_data) const; + void startGesture(LLSD const & gesture_data) const; + void stopGesture(LLSD const & gesture_data) const; + + void startOrStopGesture(LLSD const & event_data, bool start) const; +}; + +#endif // LL_LLGESTURELISTENER_H + diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 2f9856c650..66ca76bfb0 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -53,6 +53,7 @@ #include "llviewerstats.h" #include "llnearbychatbar.h" #include "llappearancemgr.h" +#include "llgesturelistener.h" // Longest time, in seconds, to wait for all animations to stop playing const F32 MAX_WAIT_ANIM_SECS = 30.f; @@ -70,6 +71,7 @@ LLGestureMgr::LLGestureMgr() mLoadingCount(0) { gInventory.addObserver(this); + mListener.reset(new LLGestureListener()); } diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index 5930841cbc..26a5924ec3 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -37,6 +37,7 @@ #include "llviewerinventory.h" class LLMultiGesture; +class LLGestureListener; class LLGestureStep; class LLUUID; class LLVFS; @@ -154,9 +155,9 @@ protected: // Used by loadGesture static void onLoadComplete(LLVFS *vfs, - const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status); + const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status); // Used by playGesture to load an asset file // required to play a gesture step @@ -185,6 +186,9 @@ private: BOOL mValid; std::set<LLUUID> mLoadingAssets; + + // LLEventHost interface + boost::shared_ptr<LLGestureListener> mListener; }; #endif diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index b5180854ef..318beafe65 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -632,10 +632,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item) } // We're hiding mesh types +#if 0 if (item->getType() == LLAssetType::AT_MESH) { return mask; } +#endif LLViewerInventoryItem* old_item = getItem(item->getUUID()); LLPointer<LLViewerInventoryItem> new_item; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index efc4e23838..ebb5912ace 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -230,7 +230,7 @@ std::string LLLogChat::makeLogFileName(std::string filename) std::string LLLogChat::cleanFileName(std::string filename) { - std::string invalidChars = "\"\'\\/?*:.<>|"; + std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars std::string::size_type position = filename.find_first_of(invalidChars); while (position != filename.npos) { diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 738d82e732..4eb94dfb8e 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -58,6 +58,7 @@ #include "llworld.h" #include "v2math.h" #include "llvoavatar.h" +#include "llmeshrepository.h" const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f; @@ -90,9 +91,7 @@ F32 get_default_max_prim_scale(bool is_flora) { // a bit of a hack, but if it's foilage, we don't want to use the // new larger scale which would result in giant trees and grass - if (gSavedSettings.getBOOL("MeshEnabled") && - gAgent.getRegion() && - !gAgent.getRegion()->getCapability("GetMesh").empty() && + if (gMeshRepo.meshRezEnabled() && !is_flora) { return DEFAULT_MAX_PRIM_SCALE; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 0a1eadf4d0..6e0722bcf9 100644..100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -61,6 +61,9 @@ #include "pipeline.h" #include "llinventorymodel.h" #include "llfoldertype.h" +#include "llviewerparcelmgr.h" + +#include "boost/lexical_cast.hpp" #ifndef LL_WINDOWS #include "netdb.h" @@ -85,6 +88,15 @@ U32 LLMeshRepository::sPeakKbps = 0; const U32 MAX_TEXTURE_UPLOAD_RETRIES = 5; +static S32 dump_num = 0; +std::string make_dump_name(std::string prefix, S32 num) +{ + return prefix + boost::lexical_cast<std::string>(num) + std::string(".xml"); + +} +void dump_llsd_to_file(const LLSD& content, std::string filename); +LLSD llsd_from_file(std::string filename); + std::string header_lod[] = { "lowest_lod", @@ -457,6 +469,55 @@ public: }; +void log_upload_error(S32 status, const LLSD& content, std::string stage, std::string model_name) +{ + // Add notification popup. + LLSD args; + std::string message = content["error"]["message"]; + std::string identifier = content["error"]["identifier"]; + args["MESSAGE"] = message; + args["IDENTIFIER"] = identifier; + args["LABEL"] = model_name; + gMeshRepo.uploadError(args); + + // Log details. + llwarns << "stage: " << stage << " http status: " << status << llendl; + if (content.has("error")) + { + const LLSD& err = content["error"]; + llwarns << "err: " << err << llendl; + llwarns << "mesh upload failed, stage '" << stage + << "' error '" << err["error"].asString() + << "', message '" << err["message"].asString() + << "', id '" << err["identifier"].asString() + << "'" << llendl; + if (err.has("errors")) + { + S32 error_num = 0; + const LLSD& err_list = err["errors"]; + for (LLSD::array_const_iterator it = err_list.beginArray(); + it != err_list.endArray(); + ++it) + { + const LLSD& err_entry = *it; + llwarns << "error[" << error_num << "]:" << llendl; + for (LLSD::map_const_iterator map_it = err_entry.beginMap(); + map_it != err_entry.endMap(); + ++map_it) + { + llwarns << "\t" << map_it->first << ": " + << map_it->second << llendl; + } + error_num++; + } + } + } + else + { + llwarns << "bad mesh, no error information available" << llendl; + } +} + class LLModelObjectUploadResponder: public LLCurl::Responder { LLSD mObjectAsset; @@ -484,20 +545,83 @@ public: class LLWholeModelFeeResponder: public LLCurl::Responder { LLMeshUploadThread* mThread; + LLSD mModelData; public: - LLWholeModelFeeResponder(LLMeshUploadThread* thread): - mThread(thread) + LLWholeModelFeeResponder(LLMeshUploadThread* thread, LLSD& model_data): + mThread(thread), + mModelData(model_data) { } - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) + virtual void completed(U32 status, + const std::string& reason, + const LLSD& content) { - assert_main_thread(); + LLSD cc = content; + if (gSavedSettings.getS32("MeshUploadFakeErrors")&1) + { + cc = llsd_from_file("fake_upload_error.xml"); + } + llinfos << "completed" << llendl; mThread->mPendingUploads--; + dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num)); + if (isGoodStatus(status) && + cc["state"].asString() == "upload") + { + llinfos << "fee request succeeded" << llendl; + mThread->mWholeModelUploadURL = cc["uploader"].asString(); + } + else + { + llwarns << "fee request failed" << llendl; + log_upload_error(status,cc,"fee",mModelData["name"]); + mThread->mWholeModelUploadURL = ""; + } } + +}; + +class LLWholeModelUploadResponder: public LLCurl::Responder +{ + LLMeshUploadThread* mThread; + LLSD mModelData; +public: + LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& model_data): + mThread(thread), + mModelData(model_data) + { + } + virtual void completed(U32 status, + const std::string& reason, + const LLSD& content) + { + LLSD cc = content; + if (gSavedSettings.getS32("MeshUploadFakeErrors")&2) + { + cc = llsd_from_file("fake_upload_error.xml"); + } + + //assert_main_thread(); + mThread->mPendingUploads--; + dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num)); + llinfos << "LLWholeModelUploadResponder content: " << cc << llendl; + // requested "mesh" asset type isn't actually the type + // of the resultant object, fix it up here. + if (isGoodStatus(status) && + cc["state"].asString() == "complete") + { + llinfos << "upload succeeded" << llendl; + mModelData["asset_type"] = "object"; + gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mModelData,cc)); + } + else + { + llwarns << "upload failed" << llendl; + std::string model_name = mModelData["name"].asString(); + log_upload_error(status,cc,"upload",model_name); + } + } }; LLMeshRepoThread::LLMeshRepoThread() @@ -671,10 +795,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) if (pending != mPendingLOD.end()) { //append this lod request to existing header request pending->second.push_back(lod); - if (pending->second.size() > 4) - { - llerrs << "WTF?" << llendl; - } + llassert(pending->second.size() <= LLModel::NUM_LODS) } else { //if no header request is pending, fetch header @@ -794,8 +915,8 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) if (header_size > 0) { - S32 offset = header_size + mMeshHeader[mesh_id]["decomposition"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["decomposition"]["size"].asInteger(); + S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger(); + S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -866,8 +987,8 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) if (header_size > 0) { - S32 offset = header_size + mMeshHeader[mesh_id]["physics_shape"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_shape"]["size"].asInteger(); + S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger(); + S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1259,9 +1380,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mOrigin = gAgent.getPositionAgent(); mHost = gAgent.getRegionHost(); - mUploadObjectAssetCapability = gAgent.getRegion()->getCapability("UploadObjectAsset"); - mNewInventoryCapability = gAgent.getRegion()->getCapability("NewFileAgentInventoryVariablePrice"); - mWholeModelUploadCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory"); + mWholeModelFeeCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory"); mOrigin += gAgent.getAtAxis() * scale.magVec(); } @@ -1280,35 +1399,7 @@ LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_mod mThread = thread; //copy out positions and indices - if (mdl) - { - U16 index_offset = 0; - - mPositions.clear(); - mIndices.clear(); - - //queue up vertex positions and indices - for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = mdl->getVolumeFace(i); - if (mPositions.size() + face.mNumVertices > 65535) - { - continue; - } - - for (U32 j = 0; j < face.mNumVertices; ++j) - { - mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); - } - - for (U32 j = 0; j < face.mNumIndices; ++j) - { - mIndices.push_back(face.mIndices[j]+index_offset); - } - - index_offset += face.mNumVertices; - } - } + assignData(mdl) ; mThread->mFinalDecomp = this; mThread->mPhysicsComplete = false; @@ -1321,11 +1412,8 @@ void LLMeshUploadThread::DecompRequest::completed() mThread->mPhysicsComplete = true; } - if (mHull.size() != 1) - { - llerrs << "WTF?" << llendl; - } - + llassert(mHull.size() == 1); + mThread->mHullMap[mBaseModel] = mHull[0]; } @@ -1353,143 +1441,199 @@ BOOL LLMeshUploadThread::isDiscarded() void LLMeshUploadThread::run() { - if (gSavedSettings.getBOOL("MeshUseWholeModelUpload")) - { - doWholeModelUpload(); - } - else + doWholeModelUpload(); +} + +void dump_llsd_to_file(const LLSD& content, std::string filename) +{ + if (gSavedSettings.getBOOL("MeshUploadLogXML")) { - doIterativeUpload(); + std::ofstream of(filename.c_str()); + LLSDSerialize::toPrettyXML(content,of); } } -#if 0 -void dumpLLSDToFile(LLSD& content, std::string& filename) +LLSD llsd_from_file(std::string filename) { - std::ofstream of(filename); - LLSDSerialize::toPrettyXML(content,of); + std::ifstream ifs(filename.c_str()); + LLSD result; + LLSDSerialize::fromXML(result,ifs); + return result; } -#endif void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) { - // TODO where do textures go? - LLSD result; + LLSD res; result["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); result["asset_type"] = "mesh"; result["inventory_type"] = "object"; - result["name"] = "your name here"; + result["name"] = "mesh model"; result["description"] = "your description here"; - // TODO "optional" fields from the spec - - LLSD res; res["mesh_list"] = LLSD::emptyArray(); res["texture_list"] = LLSD::emptyArray(); + res["instance_list"] = LLSD::emptyArray(); S32 mesh_num = 0; S32 texture_num = 0; std::set<LLViewerTexture* > textures; + std::map<LLViewerTexture*,S32> texture_index; + std::map<LLModel*,S32> mesh_index; + + S32 instance_num = 0; + for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) { LLMeshUploadData data; data.mBaseModel = iter->first; - - LLModelInstance& instance = *(iter->second.begin()); - + LLModelInstance& first_instance = *(iter->second.begin()); for (S32 i = 0; i < 5; i++) { - data.mModel[i] = instance.mLOD[i]; + data.mModel[i] = first_instance.mLOD[i]; } - std::stringstream ostr; - - LLModel::Decomposition& decomp = - data.mModel[LLModel::LOD_PHYSICS].notNull() ? - data.mModel[LLModel::LOD_PHYSICS]->mPhysics : - data.mBaseModel->mPhysics; - - decomp.mBaseHull = mHullMap[data.mBaseModel]; - - LLSD mesh_header = LLModel::writeModel( - ostr, - data.mModel[LLModel::LOD_PHYSICS], - data.mModel[LLModel::LOD_HIGH], - data.mModel[LLModel::LOD_MEDIUM], - data.mModel[LLModel::LOD_LOW], - data.mModel[LLModel::LOD_IMPOSTOR], - decomp, - mUploadSkin, - mUploadJoints); + if (mesh_index.find(data.mBaseModel) == mesh_index.end()) + { + // Have not seen this model before - create a new mesh_list entry for it. + std::string model_name = data.mBaseModel->getName(); + if (!model_name.empty()) + { + result["name"] = model_name; + } - data.mAssetData = ostr.str(); + std::stringstream ostr; + + LLModel::Decomposition& decomp = + data.mModel[LLModel::LOD_PHYSICS].notNull() ? + data.mModel[LLModel::LOD_PHYSICS]->mPhysics : + data.mBaseModel->mPhysics; - LLSD mesh_entry; + decomp.mBaseHull = mHullMap[data.mBaseModel]; - LLVector3 pos, scale; - LLQuaternion rot; - LLMatrix4 transformation = instance.mTransform; - decomposeMeshMatrix(transformation,pos,rot,scale); - - mesh_entry["childpos"] = ll_sd_from_vector3(pos); - mesh_entry["childrot"] = ll_sd_from_quaternion(rot); - mesh_entry["scale"] = ll_sd_from_vector3(scale); + LLSD mesh_header = LLModel::writeModel( + ostr, + data.mModel[LLModel::LOD_PHYSICS], + data.mModel[LLModel::LOD_HIGH], + data.mModel[LLModel::LOD_MEDIUM], + data.mModel[LLModel::LOD_LOW], + data.mModel[LLModel::LOD_IMPOSTOR], + decomp, + mUploadSkin, + mUploadJoints); - // TODO should be binary. - std::string str = ostr.str(); - mesh_entry["mesh_data"] = LLSD::Binary(str.begin(),str.end()); + data.mAssetData = ostr.str(); + std::string str = ostr.str(); - res["mesh_list"][mesh_num] = mesh_entry; + res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end()); + mesh_index[data.mBaseModel] = mesh_num; + mesh_num++; + } - // TODO how do textures in the list map to textures in the meshes? - if (mUploadTextures) + // For all instances that use this model + for (instance_list::iterator instance_iter = iter->second.begin(); + instance_iter != iter->second.end(); + ++instance_iter) { - for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin(); - material_iter != instance.mMaterial.end(); ++material_iter) - { - if (textures.find(material_iter->mDiffuseMap.get()) == textures.end()) + LLModelInstance& instance = *instance_iter; + + LLSD instance_entry; + + for (S32 i = 0; i < 5; i++) + { + data.mModel[i] = instance.mLOD[i]; + } + + LLVector3 pos, scale; + LLQuaternion rot; + LLMatrix4 transformation = instance.mTransform; + decomposeMeshMatrix(transformation,pos,rot,scale); + instance_entry["position"] = ll_sd_from_vector3(pos); + instance_entry["rotation"] = ll_sd_from_quaternion(rot); + instance_entry["scale"] = ll_sd_from_vector3(scale); + + instance_entry["material"] = LL_MCODE_WOOD; + LLPermissions perm; + perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false); + perm.setCreator(gAgent.getID()); + + perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base + PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner + LLFloaterPerms::getEveryonePerms(), + LLFloaterPerms::getGroupPerms(), + LLFloaterPerms::getNextOwnerPerms()); + instance_entry["permissions"] = ll_create_sd_from_permissions(perm); + instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); + instance_entry["mesh"] = mesh_index[data.mBaseModel]; + + instance_entry["face_list"] = LLSD::emptyArray(); + + for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++) + { + LLImportMaterial& material = instance.mMaterial[face_num]; + LLSD face_entry = LLSD::emptyMap(); + LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); + + if ((texture != NULL) && + (textures.find(texture) == textures.end())) { - textures.insert(material_iter->mDiffuseMap.get()); + textures.insert(texture); + } - std::stringstream ostr; - if (include_textures) // otherwise data is blank. - { - LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel); - if (!data.mTexture->isRawImageValid()) - { - data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); - } - + std::stringstream texture_str; + if (texture != NULL && include_textures && mUploadTextures) + { + if(texture->hasSavedRawImage()) + { LLPointer<LLImageJ2C> upload_file = - LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); - ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); + LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage()); + texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize()); } - LLSD texture_entry; - texture_entry["texture_data"] = ostr.str(); - res["texture_list"][texture_num] = texture_entry; + } + + if (texture != NULL && + mUploadTextures && + texture_index.find(texture) == texture_index.end()) + { + texture_index[texture] = texture_num; + std::string str = texture_str.str(); + res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end()); texture_num++; } - } - } - mesh_num++; + // Subset of TextureEntry fields. + if (texture != NULL && mUploadTextures) + { + face_entry["image"] = texture_index[texture]; + face_entry["scales"] = 1.0; + face_entry["scalet"] = 1.0; + face_entry["offsets"] = 0.0; + face_entry["offsett"] = 0.0; + face_entry["imagerot"] = 0.0; + } + face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor); + face_entry["fullbright"] = material.mFullbright; + instance_entry["face_list"][face_num] = face_entry; + } + + res["instance_list"][instance_num] = instance_entry; + instance_num++; + } } result["asset_resources"] = res; -#if 0 - std::string name("whole_model.xml"); - dumpLLSDToFile(result,name); -#endif + dump_llsd_to_file(result,make_dump_name("whole_model_",dump_num)); dest = result; } void LLMeshUploadThread::doWholeModelUpload() { + dump_num++; + mCurlRequest = new LLCurlRequest(); // Queue up models for hull generation (viewer-side) @@ -1521,13 +1665,13 @@ void LLMeshUploadThread::doWholeModelUpload() physics = data.mModel[LLModel::LOD_HIGH]; } - if (!physics) - { - llerrs << "WTF?" << llendl; - } - + llassert(physics != NULL); + DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this); - gMeshRepo.mDecompThread->submitRequest(request); + if(request->isValid()) + { + gMeshRepo.mDecompThread->submitRequest(request); + } } while (!mPhysicsComplete) @@ -1535,168 +1679,44 @@ void LLMeshUploadThread::doWholeModelUpload() apr_sleep(100); } - bool do_include_textures = false; // not needed for initial cost/validation check. LLSD model_data; - wholeModelToLLSD(model_data, do_include_textures); + wholeModelToLLSD(model_data,false); + dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num)); mPendingUploads++; LLCurlRequest::headers_t headers; - mCurlRequest->post(mWholeModelUploadCapability, headers, model_data.asString(), - new LLWholeModelFeeResponder(this)); - - // Currently a no-op. - mFinished = true; -} - -void LLMeshUploadThread::doIterativeUpload() -{ - if(isDiscarded()) - { - mFinished = true; - return ; - } - - mCurlRequest = new LLCurlRequest(); - - std::set<LLViewerTexture* > textures; - - //populate upload queue with relevant models - for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) - { - LLMeshUploadData data; - data.mBaseModel = iter->first; - - LLModelInstance& instance = *(iter->second.begin()); - - for (S32 i = 0; i < 5; i++) - { - data.mModel[i] = instance.mLOD[i]; - } - - uploadModel(data); - - if (mUploadTextures) - { - for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin(); - material_iter != instance.mMaterial.end(); ++material_iter) - { - - if (textures.find(material_iter->mDiffuseMap.get()) == textures.end()) - { - textures.insert(material_iter->mDiffuseMap.get()); - - LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel); - uploadTexture(data); - } - } - } - - //queue up models for hull generation - DecompRequest* request = new DecompRequest(data.mModel[LLModel::LOD_HIGH], data.mBaseModel, this); - gMeshRepo.mDecompThread->submitRequest(request); - } - - while (!mPhysicsComplete) - { - apr_sleep(100); - } + mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, + new LLWholeModelFeeResponder(this,model_data)); - //upload textures - bool done = false; do { - if (!mTextureQ.empty()) - { - sendCostRequest(mTextureQ.front()); - mTextureQ.pop(); - } - - if (!mConfirmedTextureQ.empty()) - { - doUploadTexture(mConfirmedTextureQ.front()); - mConfirmedTextureQ.pop(); - } - mCurlRequest->process(); + } while (mCurlRequest->getQueued() > 0); - done = mTextureQ.empty() && mConfirmedTextureQ.empty(); - } - while (!done || mCurlRequest->getQueued() > 0); - - LLSD object_asset; - object_asset["objects"] = LLSD::emptyArray(); - done = false; - do + if (mWholeModelUploadURL.empty()) { - static S32 count = 0; - static F32 last_hundred = gFrameTimeSeconds; - if (gFrameTimeSeconds - last_hundred > 1.f) + llinfos << "unable to upload, fee request failed" << llendl; + } + else + { + LLSD full_model_data; + wholeModelToLLSD(full_model_data, true); + LLSD body = full_model_data["asset_resources"]; + dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num)); + mCurlRequest->post(mWholeModelUploadURL, headers, body, + new LLWholeModelUploadResponder(this, model_data)); + do { - last_hundred = gFrameTimeSeconds; - count = 0; - } - - //how many requests to push before calling process - const S32 PUSH_PER_PROCESS = 32; - - S32 tcount = llmin(count+PUSH_PER_PROCESS, 100); - - while (!mUploadQ.empty() && count < tcount) - { //send any pending upload requests - mMutex->lock(); - LLMeshUploadData data = mUploadQ.front(); - mUploadQ.pop(); - mMutex->unlock(); - sendCostRequest(data); - count++; - } - - tcount = llmin(count+PUSH_PER_PROCESS, 100); - - while (!mConfirmedQ.empty() && count < tcount) - { //process any meshes that have been confirmed for upload - LLMeshUploadData& data = mConfirmedQ.front(); - doUploadModel(data); - mConfirmedQ.pop(); - count++; - } - - tcount = llmin(count+PUSH_PER_PROCESS, 100); - - while (!mInstanceQ.empty() && count < tcount && !isDiscarded()) - { //create any objects waiting for upload - count++; - object_asset["objects"].append(createObject(mInstanceQ.front())); - mInstanceQ.pop(); - } - - mCurlRequest->process(); - - done = isDiscarded() || (mInstanceQ.empty() && mConfirmedQ.empty() && mUploadQ.empty()); + mCurlRequest->process(); + } while (mCurlRequest->getQueued() > 0); } - while (!done || mCurlRequest->getQueued() > 0); delete mCurlRequest; mCurlRequest = NULL; - // now upload the object asset - std::string url = mUploadObjectAssetCapability; - - if (object_asset["objects"][0].has("permissions")) - { //copy permissions from first available object to be used for coalesced object - object_asset["permissions"] = object_asset["objects"][0]["permissions"]; - } - - if(!isDiscarded()) - { - mPendingUploads++; - LLHTTPClient::post(url, object_asset, new LLModelObjectUploadResponder(this,object_asset)); - } - else - { - mFinished = true; - } + // Currently a no-op. + mFinished = true; } void LLMeshUploadThread::uploadModel(LLMeshUploadData& data) @@ -2127,7 +2147,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, //just in case skin info or decomposition is at the end of the file (which it shouldn't be) lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger()); - lod_bytes = llmax(lod_bytes, header["decomposition"]["offset"].asInteger() + header["decomposition"]["size"].asInteger()); + lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger()); S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; S32 bytes = lod_bytes + header_bytes; @@ -2344,10 +2364,6 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para group->derefLOD(lod); } } - else - { - llerrs << "WTF?" << llendl; - } } return detail; @@ -2419,7 +2435,6 @@ void LLMeshRepository::notifyLoadedMeshes() if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived()) { region_name = gAgent.getRegion()->getName(); - mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh"); } } @@ -2527,6 +2542,20 @@ void LLMeshRepository::notifyLoadedMeshes() void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) { mSkinMap[info.mMeshID] = info; + + skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID); + if (iter != mLoadingSkins.end()) + { + for (std::set<LLUUID>::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) + { + LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); + if (vobj) + { + vobj->notifyMeshLoaded(); + } + } + } + mLoadingSkins.erase(info.mMeshID); } @@ -2642,7 +2671,7 @@ U32 LLMeshRepository::getResourceCost(const LLUUID& mesh_id) return mThread->getResourceCost(mesh_id); } -const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id) +const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj) { if (mesh_id.notNull()) { @@ -2656,12 +2685,12 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id) { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes - std::set<LLUUID>::iterator iter = mLoadingSkins.find(mesh_id); + skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); if (iter == mLoadingSkins.end()) { //no request pending for this skin info - mLoadingSkins.insert(mesh_id); mPendingSkinRequests.push(mesh_id); } + mLoadingSkins[mesh_id].insert(requesting_obj->getID()); } } @@ -2743,7 +2772,18 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail) bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) { LLSD mesh = mThread->getMeshHeader(mesh_id); - return mesh.has("physics_shape") && mesh["physics_shape"].has("size") && (mesh["physics_shape"]["size"].asInteger() > 0); + if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) + { + return true; + } + + LLModel::Decomposition* decomp = getDecomposition(mesh_id); + if (decomp && !decomp->mHull.empty()) + { + return true; + } + + return false; } LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id) @@ -2799,102 +2839,6 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) } -void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data) -{ - if(isDiscarded()) - { - return ; - } - - //write model file to memory buffer - std::stringstream ostr; - - LLModel::Decomposition& decomp = - data.mModel[LLModel::LOD_PHYSICS].notNull() ? - data.mModel[LLModel::LOD_PHYSICS]->mPhysics : - data.mBaseModel->mPhysics; - - LLSD header = LLModel::writeModel( - ostr, - data.mModel[LLModel::LOD_PHYSICS], - data.mModel[LLModel::LOD_HIGH], - data.mModel[LLModel::LOD_MEDIUM], - data.mModel[LLModel::LOD_LOW], - data.mModel[LLModel::LOD_IMPOSTOR], - decomp, - mUploadSkin, - mUploadJoints, - true); - - std::string desc = data.mBaseModel->mLabel; - - // Grab the total vertex count of the model - // along with other information for the "asset_resources" map - // to send to the server. - LLSD asset_resources = LLSD::emptyMap(); - - - std::string url = mNewInventoryCapability; - - if (!url.empty()) - { - LLSD body = generate_new_resource_upload_capability_body( - LLAssetType::AT_MESH, - desc, - desc, - LLFolderType::FT_MESH, - LLInventoryType::IT_MESH, - LLFloaterPerms::getNextOwnerPerms(), - LLFloaterPerms::getGroupPerms(), - LLFloaterPerms::getEveryonePerms()); - - body["asset_resources"] = asset_resources; - - mPendingConfirmations++; - LLCurlRequest::headers_t headers; - - data.mPostData = body; - - mCurlRequest->post(url, headers, body, new LLMeshCostResponder(data, this)); - } -} - -void LLMeshUploadThread::sendCostRequest(LLTextureUploadData& data) -{ - if(isDiscarded()) - { - return ; - } - - if (data.mTexture && data.mTexture->getDiscardLevel() >= 0) - { - LLSD asset_resources = LLSD::emptyMap(); - - std::string url = mNewInventoryCapability; - - if (!url.empty()) - { - LLSD body = generate_new_resource_upload_capability_body( - LLAssetType::AT_TEXTURE, - data.mLabel, - data.mLabel, - LLFolderType::FT_TEXTURE, - LLInventoryType::IT_TEXTURE, - LLFloaterPerms::getNextOwnerPerms(), - LLFloaterPerms::getGroupPerms(), - LLFloaterPerms::getEveryonePerms()); - - body["asset_resources"] = asset_resources; - - mPendingConfirmations++; - LLCurlRequest::headers_t headers; - - data.mPostData = body; - mCurlRequest->post(url, headers, body, new LLTextureCostResponder(data, this)); - } - } -} - void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data) { @@ -2950,9 +2894,12 @@ void LLMeshUploadThread::doUploadTexture(LLTextureUploadData& data) data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); } - LLPointer<LLImageJ2C> upload_file = LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); + if(data.mTexture->hasSavedRawImage()) + { + LLPointer<LLImageJ2C> upload_file = LLViewerTextureList::convertToUploadFile(data.mTexture->getSavedRawImage()); - ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); + ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); + } data.mAssetData = ostr.str(); @@ -3032,11 +2979,8 @@ LLSD LLMeshUploadThread::createObject(LLModelInstance& instance) { LLMatrix4 transformation = instance.mTransform; - if (instance.mMeshID.isNull()) - { - llerrs << "WTF?" << llendl; - } - + llassert(instance.mMeshID.notNull()); + // check for reflection BOOL reflected = (transformation.determinant() < 0); @@ -3200,6 +3144,8 @@ bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const void LLMeshRepository::updateInventory(inventory_data data) { LLMutexLock lock(mMeshMutex); + dump_llsd_to_file(data.mPostData,make_dump_name("update_inventory_post_data_",dump_num)); + dump_llsd_to_file(data.mResponse,make_dump_name("update_inventory_response_",dump_num)); mInventoryQ.push(data); } @@ -3357,15 +3303,18 @@ void LLPhysicsDecomp::setMeshData(LLCDMeshData& mesh) mesh.mNumTriangles = mCurRequest->mIndices.size()/3; - LLCDResult ret = LLCD_OK; - if (LLConvexDecomposition::getInstance() != NULL) + if (mesh.mNumTriangles > 0 && mesh.mNumVertices > 2) { - ret = LLConvexDecomposition::getInstance()->setMeshData(&mesh); - } + LLCDResult ret = LLCD_OK; + if (LLConvexDecomposition::getInstance() != NULL) + { + ret = LLConvexDecomposition::getInstance()->setMeshData(&mesh); + } - if (ret) - { - llerrs << "Convex Decomposition thread valid but could not set mesh data" << llendl; + if (ret) + { + llerrs << "Convex Decomposition thread valid but could not set mesh data" << llendl; + } } } @@ -3374,6 +3323,12 @@ void LLPhysicsDecomp::doDecomposition() LLCDMeshData mesh; S32 stage = mStageID[mCurRequest->mStage]; + if (LLConvexDecomposition::getInstance() == NULL) + { + // stub library. do nothing. + return; + } + //load data intoLLCD if (stage == 0) { @@ -3423,11 +3378,6 @@ void LLPhysicsDecomp::doDecomposition() { ret = LLConvexDecomposition::getInstance()->setParam(param->mName, value.asBoolean()); } - - if (ret) - { - llerrs << "WTF?" << llendl; - } } mCurRequest->setStatusMessage("Executing."); @@ -3574,6 +3524,12 @@ void LLPhysicsDecomp::doDecompositionSingleHull() LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance(); + if (decomp == NULL) + { + //stub. do nothing. + return; + } + for (S32 i = 0; i < param_count; ++i) { decomp->setParam(params[i].mName, params[i].mDefault.mIntOrEnumValue); @@ -3653,6 +3609,14 @@ void LLPhysicsDecomp::doDecompositionSingleHull() void LLPhysicsDecomp::run() { LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance(); + if (decomp == NULL) + { + // stub library. Set init to true so the main thread + // doesn't wait for this to finish. + mInited = true; + return; + } + decomp->initThread(); mInited = true; @@ -3708,6 +3672,81 @@ void LLPhysicsDecomp::run() mDone = true; } +void LLPhysicsDecomp::Request::assignData(LLModel* mdl) +{ + if (!mdl) + { + return ; + } + + U16 index_offset = 0; + U16 tri[3] ; + + mPositions.clear(); + mIndices.clear(); + mBBox[1] = LLVector3(F32_MIN, F32_MIN, F32_MIN) ; + mBBox[0] = LLVector3(F32_MAX, F32_MAX, F32_MAX) ; + + //queue up vertex positions and indices + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = mdl->getVolumeFace(i); + if (mPositions.size() + face.mNumVertices > 65535) + { + continue; + } + + for (U32 j = 0; j < face.mNumVertices; ++j) + { + mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); + for(U32 k = 0 ; k < 3 ; k++) + { + mBBox[0].mV[k] = llmin(mBBox[0].mV[k], mPositions[j].mV[k]) ; + mBBox[1].mV[k] = llmax(mBBox[1].mV[k], mPositions[j].mV[k]) ; + } + } + + updateTriangleAreaThreshold() ; + + for (U32 j = 0; j+2 < face.mNumIndices; j += 3) + { + tri[0] = face.mIndices[j] + index_offset ; + tri[1] = face.mIndices[j + 1] + index_offset ; + tri[2] = face.mIndices[j + 2] + index_offset ; + + if(isValidTriangle(tri[0], tri[1], tri[2])) + { + mIndices.push_back(tri[0]); + mIndices.push_back(tri[1]); + mIndices.push_back(tri[2]); + } + } + + index_offset += face.mNumVertices; + } + + return ; +} + +void LLPhysicsDecomp::Request::updateTriangleAreaThreshold() +{ + F32 range = mBBox[1].mV[0] - mBBox[0].mV[0] ; + range = llmin(range, mBBox[1].mV[1] - mBBox[0].mV[1]) ; + range = llmin(range, mBBox[1].mV[2] - mBBox[0].mV[2]) ; + + mTriangleAreaThreshold = llmin(0.0002f, range * 0.000002f) ; +} + +//check if the triangle area is large enough to qualify for a valid triangle +bool LLPhysicsDecomp::Request::isValidTriangle(U16 idx1, U16 idx2, U16 idx3) +{ + LLVector3 a = mPositions[idx2] - mPositions[idx1] ; + LLVector3 b = mPositions[idx3] - mPositions[idx1] ; + F32 c = a * b ; + + return ((a*a) * (b*b) - c * c) > mTriangleAreaThreshold ; +} + void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg) { mStatusMessage = msg; @@ -3805,3 +3844,27 @@ void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp) } } } + + +bool LLMeshRepository::meshUploadEnabled() +{ + LLViewerRegion *region = gAgent.getRegion(); + if(gSavedSettings.getBOOL("MeshEnabled") && + LLViewerParcelMgr::getInstance()->allowAgentBuild() && + region) + { + return region->meshUploadEnabled(); + } + return false; +} + +bool LLMeshRepository::meshRezEnabled() +{ + LLViewerRegion *region = gAgent.getRegion(); + if(gSavedSettings.getBOOL("MeshEnabled") && + region) + { + return region->meshRezEnabled(); + } + return false; +} diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 802e3e1aba..f237c3a60e 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -152,7 +152,7 @@ public: std::string mStatusMessage; std::vector<LLModel::PhysicsMesh> mHullMesh; LLModel::convex_hull_decomposition mHull; - + //status message callback, called from decomposition thread virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0; @@ -160,6 +160,17 @@ public: virtual void completed() = 0; virtual void setStatusMessage(const std::string& msg); + + bool isValid() const {return mPositions.size() > 2 && mIndices.size() > 2 ;} + + protected: + //internal use + LLVector3 mBBox[2] ; + F32 mTriangleAreaThreshold ; + + void assignData(LLModel* mdl) ; + void updateTriangleAreaThreshold() ; + bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3) ; }; LLCondition* mSignal; @@ -385,9 +396,8 @@ public: BOOL mDiscarded ; LLHost mHost; - std::string mUploadObjectAssetCapability; - std::string mNewInventoryCapability; - std::string mWholeModelUploadCapability; + std::string mWholeModelFeeCapability; + std::string mWholeModelUploadURL; std::queue<LLMeshUploadData> mUploadQ; std::queue<LLMeshUploadData> mConfirmedQ; @@ -404,12 +414,10 @@ public: void uploadTexture(LLTextureUploadData& data); void doUploadTexture(LLTextureUploadData& data); - void sendCostRequest(LLTextureUploadData& data); void priceResult(LLTextureUploadData& data, const LLSD& content); void onTextureUploaded(LLTextureUploadData& data); void uploadModel(LLMeshUploadData& data); - void sendCostRequest(LLMeshUploadData& data); void doUploadModel(LLMeshUploadData& data); void onModelUploaded(LLMeshUploadData& data); void createObjects(LLMeshUploadData& data); @@ -423,7 +431,6 @@ public: BOOL isDiscarded(); void doWholeModelUpload(); - void doIterativeUpload(); void wholeModelToLLSD(LLSD& dest, bool include_textures); @@ -466,13 +473,17 @@ public: static S32 getActualMeshLOD(LLSD& header, S32 lod); U32 calcResourceCost(LLSD& header); U32 getResourceCost(const LLUUID& mesh_params); - const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id); + const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj); LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); void buildHull(const LLVolumeParams& params, S32 detail); void buildPhysicsMesh(LLModel::Decomposition& decomp); + + bool meshUploadEnabled(); + bool meshRezEnabled(); + LLSD& getMeshHeader(const LLUUID& mesh_id); @@ -495,7 +506,8 @@ public: std::vector<LLMeshRepoThread::LODRequest> mPendingRequests; //list of mesh ids awaiting skin info - std::set<LLUUID> mLoadingSkins; + typedef std::map<LLUUID, std::set<LLUUID> > skin_load_map; + skin_load_map mLoadingSkins; //list of mesh ids that need to send skin info fetch requests std::queue<LLUUID> mPendingSkinRequests; diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index d3fd959152..4b961db5f9 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -889,11 +889,11 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); } -class LLChatHandler : public LLCommandHandler +class LLChatCommandHandler : public LLCommandHandler { public: // not allowed from outside the app - LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } + LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } // Your code here bool handle(const LLSD& tokens, const LLSD& query_map, @@ -909,7 +909,7 @@ public: { S32 channel = tokens[0].asInteger(); // VWR-19499 Restrict function to chat channels greater than 0. - if ((channel > 0) && (channel < 2147483647)) + if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG)) { retval = true; // Send unescaped message, see EXT-6353. @@ -927,6 +927,6 @@ public: }; // Creating the object registers with the dispatcher. -LLChatHandler gChatHandler; +LLChatCommandHandler gChatHandler; diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llnearbychatbarlistener.cpp new file mode 100644 index 0000000000..a63e1fb76e --- /dev/null +++ b/indra/newview/llnearbychatbarlistener.cpp @@ -0,0 +1,100 @@ +/** + * @file llnearbychatbarlistener.cpp + * @author Dave Simmons + * @date 2011-03-15 + * @brief Implementation for LLNearbyChatBarListener. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llnearbychatbarlistener.h" +#include "llnearbychatbar.h" + +#include "llagent.h" +#include "llchat.h" + + + +LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar) + : LLEventAPI("LLChatBar", + "LLChatBar listener to (e.g.) sendChat, etc."), + mChatbar(chatbar) +{ + add("sendChat", + "Send chat to the simulator:\n" + "[\"message\"] chat message text [required]\n" + "[\"channel\"] chat channel number [default = 0]\n" + "[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]", + &LLNearbyChatBarListener::sendChat); +} + + +// "sendChat" command +void LLNearbyChatBarListener::sendChat(LLSD const & chat_data) const +{ + // Extract the data + std::string chat_text = chat_data["message"].asString(); + + S32 channel = 0; + if (chat_data.has("channel")) + { + channel = chat_data["channel"].asInteger(); + if (channel < 0 || channel >= CHAT_CHANNEL_DEBUG) + { // Use 0 up to (but not including) CHAT_CHANNEL_DEBUG + channel = 0; + } + } + + EChatType type_o_chat = CHAT_TYPE_NORMAL; + if (chat_data.has("type")) + { + std::string type_string = chat_data["type"].asString(); + if (type_string == "whisper") + { + type_o_chat = CHAT_TYPE_WHISPER; + } + else if (type_string == "shout") + { + type_o_chat = CHAT_TYPE_SHOUT; + } + } + + // Have to prepend /42 style channel numbers + std::string chat_to_send; + if (channel == 0) + { + chat_to_send = chat_text; + } + else + { + chat_to_send += "/"; + chat_to_send += chat_data["channel"].asString(); + chat_to_send += " "; + chat_to_send += chat_text; + } + + // Send it as if it was typed in + mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0)); +} + diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llnearbychatbarlistener.h new file mode 100644 index 0000000000..9af9bc1f7b --- /dev/null +++ b/indra/newview/llnearbychatbarlistener.h @@ -0,0 +1,50 @@ +/** + * @file llnearbychatbarlistener.h + * @author Dave Simmons + * @date 2011-03-15 + * @brief Class definition for LLNearbyChatBarListener. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#ifndef LL_LLNEARBYCHATBARLISTENER_H +#define LL_LLNEARBYCHATBARLISTENER_H + +#include "lleventapi.h" + +class LLSD; +class LLNearbyChatBar; + +class LLNearbyChatBarListener : public LLEventAPI +{ +public: + LLNearbyChatBarListener(LLNearbyChatBar & chatbar); + +private: + void sendChat(LLSD const & chat_data) const; + + LLNearbyChatBar & mChatbar; +}; + +#endif // LL_LLNEARBYCHATBARLISTENER_H + diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index b56fb65a4c..11dc496311 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -441,6 +441,8 @@ void LLNearbyChatScreenChannel::reshape (S32 width, S32 height, BOOL called_fr //----------------------------------------------------------------------------------------------- //LLNearbyChatHandler //----------------------------------------------------------------------------------------------- +boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat")); + LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id) { mType = type; @@ -487,6 +489,27 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) // tmp_chat.mFromName = tmp_chat.mFromID.asString(); } + // Build notification data + LLSD notification; + notification["message"] = chat_msg.mText; + notification["from"] = chat_msg.mFromName; + notification["from_id"] = chat_msg.mFromID; + notification["time"] = chat_msg.mTime; + notification["source"] = (S32)chat_msg.mSourceType; + notification["chat_type"] = (S32)chat_msg.mChatType; + notification["chat_style"] = (S32)chat_msg.mChatStyle; + // Pass sender info so that it can be rendered properly (STORM-1021). + notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args); + + if (chat_msg.mChatType == CHAT_TYPE_DIRECT && + chat_msg.mText.length() > 0 && + chat_msg.mText[0] == '@') + { + // Send event on to LLEventStream and exit + sChatWatcher->post(notification); + return; + } + // don't show toast and add message to chat history on receive debug message // with disabled setting showing script errors or enabled setting to show script // errors in separate window. @@ -529,6 +552,10 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) } + // Send event on to LLEventStream + sChatWatcher->post(notification); + + if( nearby_chat->getVisible() || ( chat_msg.mSourceType == CHAT_SOURCE_AGENT && gSavedSettings.getBOOL("UseChatBubbles") ) @@ -562,25 +589,14 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) } */ - // Add a nearby chat toast. - LLUUID id; - id.generate(); - LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel); - if(channel) { - LLSD notification; + // Add a nearby chat toast. + LLUUID id; + id.generate(); notification["id"] = id; - notification["message"] = chat_msg.mText; - notification["from"] = chat_msg.mFromName; - notification["from_id"] = chat_msg.mFromID; - notification["time"] = chat_msg.mTime; - notification["source"] = (S32)chat_msg.mSourceType; - notification["chat_type"] = (S32)chat_msg.mChatType; - notification["chat_style"] = (S32)chat_msg.mChatStyle; - std::string r_color_name = "White"; F32 r_color_alpha = 1.0f; LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha); @@ -588,13 +604,8 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) notification["text_color"] = r_color_name; notification["color_alpha"] = r_color_alpha; notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ; - - // Pass sender info so that it can be rendered properly (STORM-1021). - notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args); - channel->addNotification(notification); } - } void LLNearbyChatHandler::onDeleteToast(LLToast* toast) diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h index ec1f29cdfc..b0e4f62d51 100644 --- a/indra/newview/llnearbychathandler.h +++ b/indra/newview/llnearbychathandler.h @@ -29,6 +29,8 @@ #include "llnotificationhandler.h" +class LLEventPump; + //add LLNearbyChatHandler to LLNotificationsUI namespace namespace LLNotificationsUI{ @@ -44,6 +46,8 @@ public: protected: virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); + + static boost::scoped_ptr<LLEventPump> sChatWatcher; }; } diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h index 72fa394621..16e82e4cce 100644 --- a/indra/newview/llnotificationmanager.h +++ b/indra/newview/llnotificationmanager.h @@ -69,7 +69,7 @@ public: private: //TODO (*) std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers; - std::map<std::string, LLChatHandler*> mChatHandlers; + // cruft std::map<std::string, LLChatHandler*> mChatHandlers; }; } diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 80f6862169..c2729fa19b 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -299,7 +299,7 @@ void LLLandmarksPanel::onTeleport() } LLFolderViewEventListener* listenerp = current_item->getListener(); - if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) + if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) { listenerp->openItem(); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index d0810d0772..27f341b4f6 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -34,7 +34,6 @@ #include "llmd5.h" #include "llsecondlifeurls.h" #include "v4color.h" -#include "llversionviewer.h" #include "llappviewer.h" #include "llbutton.h" @@ -748,20 +747,12 @@ void LLPanelLogin::loadLoginPage() LLVersionInfo::getShortVersion().c_str(), LLVersionInfo::getBuild()); - char* curl_channel ; + char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0); char* curl_version = curl_escape(version.c_str(), 0); - if(strcmp(LLVersionInfo::getChannel().c_str(), LL_CHANNEL)) - { - curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0); - } - else //if LL_CHANNEL, direct it to "Second Life Beta Viewer". - { - curl_channel = curl_escape("Second Life Beta Viewer", 0); - } oStr << "&channel=" << curl_channel; oStr << "&version=" << curl_version; - + curl_free(curl_channel); curl_free(curl_version); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 64af6c2157..52917ff20b 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -33,11 +33,9 @@ #include "lleconomy.h" #include "llerror.h" #include "llfontgl.h" -#include "llmaterialtable.h" #include "llpermissionsflags.h" #include "llstring.h" #include "llvolume.h" -#include "material_codes.h" #include "m3math.h" // project includes @@ -57,7 +55,6 @@ #include "lltool.h" #include "lltoolcomp.h" #include "lltoolmgr.h" -#include "lltrans.h" #include "llui.h" #include "llviewerobject.h" #include "llviewerregion.h" @@ -101,17 +98,6 @@ BOOL LLPanelObject::postBuild() { setMouseOpaque(FALSE); - std::map<std::string, std::string> material_name_map; - material_name_map["Stone"]= LLTrans::getString("Stone"); - material_name_map["Metal"]= LLTrans::getString("Metal"); - material_name_map["Glass"]= LLTrans::getString("Glass"); - material_name_map["Wood"]= LLTrans::getString("Wood"); - material_name_map["Flesh"]= LLTrans::getString("Flesh"); - material_name_map["Plastic"]= LLTrans::getString("Plastic"); - material_name_map["Rubber"]= LLTrans::getString("Rubber"); - material_name_map["Light"]= LLTrans::getString("Light"); - - LLMaterialTable::basic.initTableTransNames(material_name_map); //-------------------------------------------------------- // Top //-------------------------------------------------------- @@ -166,22 +152,6 @@ BOOL LLPanelObject::postBuild() //-------------------------------------------------------- - // material type popup - mComboMaterial = getChild<LLComboBox>("material"); - childSetCommitCallback("material",onCommitMaterial,this); - mComboMaterial->removeall(); - - for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin(); - iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo* minfop = *iter; - if (minfop->mMCode != LL_MCODE_LIGHT) - { - mComboMaterial->add(minfop->mName); - } - } - mComboMaterialItemCount = mComboMaterial->getItemCount(); - // Base Type mComboBaseType = getChild<LLComboBox>("comboBaseType"); childSetCommitCallback("comboBaseType",onCommitParametric,this); @@ -309,7 +279,6 @@ BOOL LLPanelObject::postBuild() LLPanelObject::LLPanelObject() : LLPanel(), - mComboMaterialItemCount(0), mIsPhysical(FALSE), mIsTemporary(FALSE), mIsPhantom(FALSE), @@ -527,43 +496,6 @@ void LLPanelObject::getState( ) mCheckCastShadows->setEnabled( roots_selected==1 && editable ); #endif - // Update material part - // slightly inefficient - materials are unique per object, not per TE - U8 material_code = 0; - struct f : public LLSelectedTEGetFunctor<U8> - { - U8 get(LLViewerObject* object, S32 te) - { - return object->getMaterial(); - } - } func; - bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code ); - std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); - if (editable && single_volume && material_same) - { - mComboMaterial->setEnabled( TRUE ); - if (material_code == LL_MCODE_LIGHT) - { - if (mComboMaterial->getItemCount() == mComboMaterialItemCount) - { - mComboMaterial->add(LEGACY_FULLBRIGHT_DESC); - } - mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC); - } - else - { - if (mComboMaterial->getItemCount() != mComboMaterialItemCount) - { - mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC); - } - - mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code))); - } - } - else - { - mComboMaterial->setEnabled( FALSE ); - } //---------------------------------------------------------------------------- S32 selected_item = MI_BOX; @@ -1095,12 +1027,9 @@ void LLPanelObject::getState( ) mCtrlSculptTexture->setVisible(sculpt_texture_visible); mLabelSculptType->setVisible(sculpt_texture_visible); mCtrlSculptType->setVisible(sculpt_texture_visible); - mCtrlSculptMirror->setVisible(sculpt_texture_visible); - mCtrlSculptInvert->setVisible(sculpt_texture_visible); // sculpt texture - if (selected_item == MI_SCULPT) { @@ -1145,7 +1074,7 @@ void LLPanelObject::getState( ) if (mCtrlSculptMirror) { mCtrlSculptMirror->set(sculpt_mirror); - mCtrlSculptMirror->setEnabled(editable); + mCtrlSculptMirror->setEnabled(editable && !isMesh); } if (mCtrlSculptInvert) @@ -1166,6 +1095,9 @@ void LLPanelObject::getState( ) mSculptTextureRevert = LLUUID::null; } + mCtrlSculptMirror->setVisible(sculpt_texture_visible && !isMesh); + mCtrlSculptInvert->setVisible(sculpt_texture_visible && !isMesh); + //---------------------------------------------------------------------------- mObject = objectp; @@ -1245,25 +1177,6 @@ void LLPanelObject::sendCastShadows() } // static -void LLPanelObject::onCommitMaterial( LLUICtrl* ctrl, void* userdata ) -{ - //LLPanelObject* self = (LLPanelObject*) userdata; - LLComboBox* box = (LLComboBox*) ctrl; - - if (box) - { - // apply the currently selected material to the object - const std::string& material_name = box->getSimple(); - std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); - if (material_name != LEGACY_FULLBRIGHT_DESC) - { - U8 material_code = LLMaterialTable::basic.getMCode(material_name); - LLSelectMgr::getInstance()->selectionSetMaterial(material_code); - } - } -} - -// static void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata ) { LLPanelObject* self = (LLPanelObject*) userdata; @@ -1827,25 +1740,11 @@ void LLPanelObject::refresh() mRootObject = NULL; } - bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && - gAgent.getRegion() && - !gAgent.getRegion()->getCapability("GetMesh").empty(); - F32 max_scale = get_default_max_prim_scale(LLPickInfo::isFlora(mObject)); getChild<LLSpinCtrl>("Scale X")->setMaxValue(max_scale); getChild<LLSpinCtrl>("Scale Y")->setMaxValue(max_scale); getChild<LLSpinCtrl>("Scale Z")->setMaxValue(max_scale); - - BOOL found = mCtrlSculptType->itemExists("Mesh"); - if (enable_mesh && !found) - { - mCtrlSculptType->add("Mesh"); - } - else if (!enable_mesh && found) - { - mCtrlSculptType->remove("Mesh"); - } } @@ -1937,7 +1836,6 @@ void LLPanelObject::clearCtrls() mCheckCastShadows->set(FALSE); mCheckCastShadows->setEnabled( FALSE ); #endif - mComboMaterial ->setEnabled( FALSE ); // Disable text labels mLabelPosition ->setEnabled( FALSE ); mLabelSize ->setEnabled( FALSE ); diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index e2f2a4400d..475dfdaedb 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -66,7 +66,6 @@ public: static void onCommitPhantom( LLUICtrl* ctrl, void* userdata); static void onCommitCastShadows( LLUICtrl* ctrl, void* userdata); static void onCommitPhysics( LLUICtrl* ctrl, void* userdata); - static void onCommitMaterial( LLUICtrl* ctrl, void* userdata); static void onCommitParametric(LLUICtrl* ctrl, void* userdata); @@ -94,10 +93,6 @@ protected: void getVolumeParams(LLVolumeParams& volume_params); protected: - S32 mComboMaterialItemCount; - - LLComboBox* mComboMaterial; - // Per-object options LLComboBox* mComboBaseType; diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index ddce83c616..ddce83c616 100644..100755 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 29db110523..29db110523 100644..100755 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 46262832dc..1e510a2d7b 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -584,6 +584,13 @@ void LLPanelPlaces::onTeleportButtonClicked() { if (mPlaceInfoType == LANDMARK_INFO_TYPE) { + if (mItem.isNull()) + { + llwarns << "NULL landmark item" << llendl; + llassert(mItem.notNull()); + return; + } + LLSD payload; payload["asset_id"] = mItem->getAssetUUID(); LLSD args; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index fd5c3362bb..fd5c3362bb 100644..100755 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index fca359f51e..fca359f51e 100644..100755 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp index dc87bd0077..4a80bbbe5e 100644 --- a/indra/newview/llpanelvoicedevicesettings.cpp +++ b/indra/newview/llpanelvoicedevicesettings.cpp @@ -191,7 +191,21 @@ void LLPanelVoiceDeviceSettings::refresh() mCtrlInputDevices = getChild<LLComboBox>("voice_input_device"); mCtrlOutputDevices = getChild<LLComboBox>("voice_output_device"); - if(!LLVoiceClient::getInstance()->deviceSettingsAvailable()) + bool device_settings_available = LLVoiceClient::getInstance()->deviceSettingsAvailable(); + + if (mCtrlInputDevices) + { + mCtrlInputDevices->setEnabled(device_settings_available); + } + + if (mCtrlOutputDevices) + { + mCtrlOutputDevices->setEnabled(device_settings_available); + } + + getChild<LLSlider>("mic_volume_slider")->setEnabled(device_settings_available); + + if(!device_settings_available) { // The combo boxes are disabled, since we can't get the device settings from the daemon just now. // Put the currently set default (ONLY) in the box, and select it. @@ -207,6 +221,7 @@ void LLPanelVoiceDeviceSettings::refresh() mCtrlOutputDevices->add( mOutputDevice, ADD_BOTTOM ); mCtrlOutputDevices->setSimple(mOutputDevice); } + mDevicesUpdated = FALSE; } else if (!mDevicesUpdated) { diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index c443814c89..bb87601d20 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -59,6 +59,7 @@ #include "lltool.h" #include "lltoolcomp.h" #include "lltoolmgr.h" +#include "lltrans.h" #include "llui.h" #include "llviewerobject.h" #include "llviewerregion.h" @@ -156,6 +157,34 @@ BOOL LLPanelVolume::postBuild() mSpinPhysicsRestitution = getChild<LLSpinCtrl>("Physics Restitution"); mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution)); } + + std::map<std::string, std::string> material_name_map; + material_name_map["Stone"]= LLTrans::getString("Stone"); + material_name_map["Metal"]= LLTrans::getString("Metal"); + material_name_map["Glass"]= LLTrans::getString("Glass"); + material_name_map["Wood"]= LLTrans::getString("Wood"); + material_name_map["Flesh"]= LLTrans::getString("Flesh"); + material_name_map["Plastic"]= LLTrans::getString("Plastic"); + material_name_map["Rubber"]= LLTrans::getString("Rubber"); + material_name_map["Light"]= LLTrans::getString("Light"); + + LLMaterialTable::basic.initTableTransNames(material_name_map); + + // material type popup + mComboMaterial = getChild<LLComboBox>("material"); + childSetCommitCallback("material",onCommitMaterial,this); + mComboMaterial->removeall(); + + for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin(); + iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo* minfop = *iter; + if (minfop->mMCode != LL_MCODE_LIGHT) + { + mComboMaterial->add(minfop->mName); + } + } + mComboMaterialItemCount = mComboMaterial->getItemCount(); // Start with everyone disabled clearCtrls(); @@ -164,7 +193,8 @@ BOOL LLPanelVolume::postBuild() } LLPanelVolume::LLPanelVolume() - : LLPanel() + : LLPanel(), + mComboMaterialItemCount(0) { setMouseOpaque(FALSE); @@ -379,6 +409,46 @@ void LLPanelVolume::getState( ) getChildView("FlexForceZ")->setEnabled(false); } + // Material properties + + // Update material part + // slightly inefficient - materials are unique per object, not per TE + U8 material_code = 0; + struct f : public LLSelectedTEGetFunctor<U8> + { + U8 get(LLViewerObject* object, S32 te) + { + return object->getMaterial(); + } + } func; + bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code ); + std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); + if (editable && single_volume && material_same) + { + mComboMaterial->setEnabled( TRUE ); + if (material_code == LL_MCODE_LIGHT) + { + if (mComboMaterial->getItemCount() == mComboMaterialItemCount) + { + mComboMaterial->add(LEGACY_FULLBRIGHT_DESC); + } + mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC); + } + else + { + if (mComboMaterial->getItemCount() != mComboMaterialItemCount) + { + mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC); + } + + mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code))); + } + } + else + { + mComboMaterial->setEnabled( FALSE ); + } + // Physics properties mSpinPhysicsGravity->set(objectp->getPhysicsGravity()); @@ -460,17 +530,24 @@ void LLPanelVolume::refresh() getChildView("Light Ambiance")->setVisible( visible); getChildView("light texture control")->setVisible( visible); - bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && - gAgent.getRegion() && - !gAgent.getRegion()->getCapability("GetMesh").empty(); + bool enable_mesh = false; + LLSD sim_features; + LLViewerRegion *region = gAgent.getRegion(); + if(region) + { + LLSD sim_features; + region->getSimulatorFeatures(sim_features); + enable_mesh = sim_features.has("PhysicsShapeTypes"); + } getChildView("label physicsshapetype")->setVisible(enable_mesh); getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh); getChildView("Physics Gravity")->setVisible(enable_mesh); - getChildView("Physics Material Override")->setVisible(enable_mesh); getChildView("Physics Friction")->setVisible(enable_mesh); getChildView("Physics Density")->setVisible(enable_mesh); getChildView("Physics Restitution")->setVisible(enable_mesh); + + /* TODO: add/remove individual physics shape types as per the PhysicsShapeTypes simulator features */ } @@ -522,6 +599,8 @@ void LLPanelVolume::clearCtrls() mSpinPhysicsFriction->setEnabled(FALSE); mSpinPhysicsDensity->setEnabled(FALSE); mSpinPhysicsRestitution->setEnabled(FALSE); + + mComboMaterial->setEnabled( FALSE ); } // @@ -674,6 +753,25 @@ void LLPanelVolume::onLightSelectTexture(const LLSD& data) } // static +void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata ) +{ + //LLPanelObject* self = (LLPanelObject*) userdata; + LLComboBox* box = (LLComboBox*) ctrl; + + if (box) + { + // apply the currently selected material to the object + const std::string& material_name = box->getSimple(); + std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); + if (material_name != LEGACY_FULLBRIGHT_DESC) + { + U8 material_code = LLMaterialTable::basic.getMCode(material_name); + LLSelectMgr::getInstance()->selectionSetMaterial(material_code); + } + } +} + +// static void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) { LLPanelVolume* self = (LLPanelVolume*) userdata; diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index 776a2c1f4a..0ef47db0d9 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -63,8 +63,8 @@ public: static void onCommitLight( LLUICtrl* ctrl, void* userdata); static void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); static void onCommitFlexible( LLUICtrl* ctrl, void* userdata); - static void onCommitPhysicsParam( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterial( LLUICtrl* ctrl, void* userdata); void onLightCancelColor(const LLSD& data); void onLightSelectColor(const LLSD& data); @@ -104,6 +104,10 @@ protected: LLSpinCtrl* mSpinForce[3]; */ + S32 mComboMaterialItemCount; + LLComboBox* mComboMaterial; + + LLColor4 mLightSavedColor; LLUUID mLightSavedTexture; LLPointer<LLViewerObject> mObject; diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 9f3ee6ac5d..4974dde282 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -401,15 +401,14 @@ struct LLSaveNotecardInfo bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) { - if(!gAssetStorage) + LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor"); + + if(!editor) { - llwarns << "Not connected to an asset storage system." << llendl; + llwarns << "Cannot get handle to the notecard editor." << llendl; return false; } - - LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor"); - if(!editor->isPristine()) { // We need to update the asset information @@ -436,8 +435,15 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) // save it out to database if (item) { - std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory"); - std::string task_url = gAgent.getRegion()->getCapability("UpdateNotecardTaskInventory"); + const LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + llwarns << "Not connected to a region, cannot save notecard." << llendl; + return false; + } + std::string agent_url = region->getCapability("UpdateNotecardAgentInventory"); + std::string task_url = region->getCapability("UpdateNotecardTaskInventory"); + if (mObjectUUID.isNull() && !agent_url.empty()) { // Saving into agent inventory @@ -472,6 +478,11 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) (void*)info, FALSE); } + else // !gAssetStorage + { + llwarns << "Not connected to an asset storage system." << llendl; + return false; + } } } return true; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 9b264b81c7..8fa4065fa6 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1997,7 +1997,7 @@ void LLSelectMgr::selectionSetPhysicsType(U8 type) if (object->permModify()) { object->setPhysicsShapeType(mType); - object->updateFlags(); + object->updateFlags(TRUE); } return true; } @@ -2016,7 +2016,7 @@ void LLSelectMgr::selectionSetFriction(F32 friction) if (object->permModify()) { object->setPhysicsFriction(mFriction); - object->updateFlags(); + object->updateFlags(TRUE); } return true; } @@ -2035,7 +2035,7 @@ void LLSelectMgr::selectionSetGravity(F32 gravity ) if (object->permModify()) { object->setPhysicsGravity(mGravity); - object->updateFlags(); + object->updateFlags(TRUE); } return true; } @@ -2054,7 +2054,7 @@ void LLSelectMgr::selectionSetDensity(F32 density ) if (object->permModify()) { object->setPhysicsDensity(mDensity); - object->updateFlags(); + object->updateFlags(TRUE); } return true; } @@ -2073,7 +2073,7 @@ void LLSelectMgr::selectionSetRestitution(F32 restitution) if (object->permModify()) { object->setPhysicsRestitution(mRestitution); - object->updateFlags(); + object->updateFlags(TRUE); } return true; } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index fa329eb0ae..a5b91729e8 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -35,6 +35,7 @@ #include "llvolumeoctree.h" #include "llviewercamera.h" #include "llface.h" +#include "llfloatertools.h" #include "llviewercontrol.h" #include "llviewerregion.h" #include "llcamera.h" @@ -69,6 +70,7 @@ U32 LLSpatialGroup::sNodeCount = 0; std::set<GLuint> LLSpatialGroup::sPendingQueries; +U32 gOctreeMaxCapacity; BOOL LLSpatialGroup::sNoDelete = FALSE; @@ -630,7 +632,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) if (mOctreeNode->isInside(drawablep->getPositionGroup()) && (mOctreeNode->contains(drawablep) || (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && - parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) + parent && parent->getElementCount() >= gOctreeMaxCapacity))) { unbound(); setState(OBJECT_DIRTY); @@ -689,17 +691,8 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - /*if (!gPipeline.hasRenderType(mDrawableType)) - { - return; - }*/ - if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) { - /*if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && mRenderByGroup) - { - llerrs << "WTF?" << llendl; - }*/ return; } @@ -961,21 +954,15 @@ void LLSpatialGroup::setState(U32 state) { mState |= state; - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); } void LLSpatialGroup::setState(U32 state, S32 mode) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } - + llassert(state <= LLSpatialGroup::STATE_MASK); + if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -1021,20 +1008,14 @@ public: void LLSpatialGroup::clearState(U32 state) { - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); mState &= ~state; } void LLSpatialGroup::clearState(U32 state, S32 mode) { - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -1059,10 +1040,7 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) BOOL LLSpatialGroup::isState(U32 state) const { - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); return mState & state ? TRUE : FALSE; } @@ -1250,7 +1228,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) { if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { - llerrs << "WTF?" << llendl; + llwarns << "Attempted to update distance for camera other than world camera!" << llendl; + return; } #if !LL_RELEASE_FOR_DOWNLOAD @@ -2064,11 +2043,8 @@ public: virtual void processGroup(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) - { - llerrs << "WTF?" << llendl; - } - + llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty()) + if (mRes < 2) { if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) @@ -2541,7 +2517,7 @@ void renderOctree(LLSpatialGroup* group) //coded by buffer usage and activity gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); LLVector4 col; - if (group->mBuilt > 0.f) + /*if (group->mBuilt > 0.f) { group->mBuilt -= 2.f * gFrameIntervalSeconds; if (group->mBufferUsage == GL_STATIC_DRAW_ARB) @@ -2610,7 +2586,7 @@ void renderOctree(LLSpatialGroup* group) gGL.color4f(1,1,1,1); } } - else + else*/ { if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty() && group->mSpatialPartition->mRenderByGroup) @@ -2630,33 +2606,24 @@ void renderOctree(LLSpatialGroup* group) size.mul(1.01f); size.add(fudge); - { - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - drawBox(group->mObjectBounds[0], fudge); - } + //{ + // LLGLDepthTest depth(GL_TRUE, GL_FALSE); + // drawBox(group->mObjectBounds[0], fudge); + //} gGL.setSceneBlendType(LLRender::BT_ALPHA); - if (group->mBuilt <= 0.f) + //if (group->mBuilt <= 0.f) { //draw opaque outline - gGL.color4f(col.mV[0], col.mV[1], col.mV[2], 1.f); - drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); + //gGL.color4f(col.mV[0], col.mV[1], col.mV[2], 1.f); + //drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); - if (group->mOctreeNode->isLeaf()) - { - gGL.color4f(1,1,1,1); - } - else - { - gGL.color4f(0,1,1,1); - } - + gGL.color4f(0,1,1,1); drawBoxOutline(group->mBounds[0],group->mBounds[1]); - - + //draw bounding box for draw info - if (group->mSpatialPartition->mRenderByGroup) + /*if (group->mSpatialPartition->mRenderByGroup) { gGL.color4f(1.0f, 0.75f, 0.25f, 0.6f); for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -2673,7 +2640,7 @@ void renderOctree(LLSpatialGroup* group) drawBoxOutline(center, size); } } - } + }*/ } // LLSpatialGroup::OctreeNode* node = group->mOctreeNode; @@ -2716,7 +2683,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) gGL.color4f(0.f, 0.75f, 0.f, 0.5f); pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } - else if (camera && group->mOcclusionVerts.notNull()) + /*else if (camera && group->mOcclusionVerts.notNull()) { LLVertexBuffer::unbind(); group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); @@ -2728,7 +2695,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) glColor4f(1.0f, 1.f, 1.f, 1.0f); group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } + }*/ } } @@ -3002,13 +2969,6 @@ void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColo void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) { - if (volume->isSelected()) - { - LLVector3 construct_me(5,5,5); - construct_me.normalize(); - } - - U8 physics_type = volume->getPhysicsShapeType(); if (physics_type == LLViewerObject::PHYSICS_SHAPE_NONE || volume->isFlexible()) @@ -3473,6 +3433,8 @@ void renderTextureAnim(LLDrawInfo* params) void renderBatchSize(LLDrawInfo* params) { + LLGLEnable offset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.f, 1.f); glColor3ubv((GLubyte*) &(params->mDebugColor)); pushVerts(params, LLVertexBuffer::MAP_VERTEX); } @@ -3910,6 +3872,28 @@ public: renderAgentTarget(avatar); } + if (gDebugGL) + { + for (U32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* facep = drawable->getFace(i); + U8 index = facep->getTextureIndex(); + if (facep->mDrawInfo) + { + if (index < 255) + { + if (facep->mDrawInfo->mTextureList.size() <= index) + { + llerrs << "Face texture index out of bounds." << llendl; + } + else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) + { + llerrs << "Face texture index incorrect." << llendl; + } + } + } + } + } } for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -4282,7 +4266,29 @@ public: if (vobj) { LLVector3 intersection; - if (vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) + bool skip_check = false; + if (vobj->isAvatar()) + { + LLVOAvatar* avatar = (LLVOAvatar*) vobj; + if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools)) + { + LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal); + if (hit) + { + mEnd = intersection; + if (mIntersection) + { + *mIntersection = intersection; + } + + mHit = hit->mDrawable; + skip_check = true; + } + + } + } + + if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) { mEnd = intersection; // shorten ray so we only find CLOSER hits if (mIntersection) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 0d9cad914a..db8a0c2992 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -91,6 +91,8 @@ public: LLPointer<LLVertexBuffer> mVertexBuffer; LLPointer<LLViewerTexture> mTexture; + std::vector<LLPointer<LLViewerTexture> > mTextureList; + LLColor4U mGlowColor; S32 mDebugColor; const LLMatrix4* mTextureMatrix; @@ -207,7 +209,7 @@ public: typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t; typedef std::map<U32, drawmap_elem_t > draw_map_t; typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t; - typedef std::map<LLPointer<LLViewerTexture>, buffer_list_t> buffer_texture_map_t; + typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t; typedef std::map<U32, buffer_texture_map_t> buffer_map_t; typedef LLOctreeListener<LLDrawable> BaseType; @@ -399,7 +401,7 @@ protected: public: bridge_list_t mBridgeList; - buffer_map_t mBufferMap; //used by volume buffers to store unique buffers per texture + buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers F32 mBuilt; OctreeNode* mOctreeNode; @@ -684,7 +686,7 @@ class LLVolumeGeometryManager: public LLGeometryManager virtual void rebuildGeom(LLSpatialGroup* group); virtual void rebuildMesh(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group); - void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE); + void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE); void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 141a81c717..86b09473ab 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1970,7 +1970,6 @@ bool idle_startup() // Start automatic replay if the flag is set. if (gSavedSettings.getBOOL("StatsAutoRun") || gAgentPilot.getReplaySession()) { - LLUUID id; LL_DEBUGS("AppInit") << "Starting automatic playback" << LL_ENDL; gAgentPilot.startPlayback(); } diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 7fb52c1939..9b417307fd 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -949,7 +949,7 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache max_size -= sCacheMaxTexturesSize; LL_INFOS("TextureCache") << "Headers: " << sCacheMaxEntries - << " Textures size: " << sCacheMaxTexturesSize/(1024*1024) << " MB" << LL_ENDL; + << " Textures size: " << sCacheMaxTexturesSize / (1024 * 1024) << " MB" << LL_ENDL; setDirNames(location); @@ -1513,12 +1513,12 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) { const char* subdirs = "0123456789abcdef"; std::string delem = gDirUtilp->getDirDelimiter(); - std::string mask = delem + "*"; + std::string mask = "*"; for (S32 i=0; i<16; i++) { std::string dirname = mTexturesDirName + delem + subdirs[i]; llinfos << "Deleting files in directory: " << dirname << llendl; - gDirUtilp->deleteFilesInDir(dirname,mask); + gDirUtilp->deleteFilesInDir(dirname, mask); if (purge_directories) { LLFile::rmdir(dirname); @@ -1655,7 +1655,7 @@ void LLTextureCache::purgeTextures(bool validate) LL_INFOS("TextureCache") << "TEXTURE CACHE:" << " PURGED: " << purge_count << " ENTRIES: " << num_entries - << " CACHE SIZE: " << mTexturesSizeTotal / 1024*1024 << " MB" + << " CACHE SIZE: " << mTexturesSizeTotal / (1024 * 1024) << " MB" << llendl; } diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index b6c0f662e5..319e2508e0 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -54,7 +54,6 @@ #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" -#include "llviewerwindow.h" #include "llvoavatarself.h" #include "llworld.h" @@ -387,22 +386,7 @@ void LLToolGrab::startGrab() mDragStartPointGlobal = grab_start_global; mDragStartFromCamera = grab_start_global - gAgentCamera.getCameraPositionGlobal(); - LLMessageSystem *msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ObjectGrab); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID); - msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset ); - msg->nextBlock("SurfaceInfo"); - msg->addVector3("UVCoord", LLVector3(mGrabPick.mUVCoords)); - msg->addVector3("STCoord", LLVector3(mGrabPick.mSTCoords)); - msg->addS32Fast(_PREHASH_FaceIndex, mGrabPick.mObjectFace); - msg->addVector3("Position", mGrabPick.mIntersection); - msg->addVector3("Normal", mGrabPick.mNormal); - msg->addVector3("Binormal", mGrabPick.mBinormal); - msg->sendMessage( objectp->getRegion()->getHost()); + send_ObjectGrab_message(objectp, mGrabPick, grab_offset); mGrabOffsetFromCenterInitial = grab_offset; mGrabHiddenOffsetFromCamera = mDragStartFromCamera; @@ -1036,28 +1020,12 @@ void LLToolGrab::stopGrab() } // Next, send messages to simulator - LLMessageSystem *msg = gMessageSystem; switch(mMode) { case GRAB_ACTIVE_CENTER: case GRAB_NONPHYSICAL: case GRAB_LOCKED: - msg->newMessageFast(_PREHASH_ObjectDeGrab); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID); - msg->nextBlock("SurfaceInfo"); - msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); - msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); - msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); - msg->addVector3("Position", pick.mIntersection); - msg->addVector3("Normal", pick.mNormal); - msg->addVector3("Binormal", pick.mBinormal); - - msg->sendMessage(objectp->getRegion()->getHost()); - + send_ObjectDeGrab_message(objectp, pick); mVerticalDragging = FALSE; break; @@ -1109,3 +1077,66 @@ LLVector3d LLToolGrab::getGrabPointGlobal() return gAgent.getPositionGlobal(); } } + + +void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, const LLVector3 &grab_offset) +{ + if (!object) return; + + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ObjectGrab); + msg->nextBlockFast( _PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast( _PREHASH_ObjectData); + msg->addU32Fast( _PREHASH_LocalID, object->mLocalID); + msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset); + msg->nextBlock("SurfaceInfo"); + msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); + msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); + msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); + msg->addVector3("Position", pick.mIntersection); + msg->addVector3("Normal", pick.mNormal); + msg->addVector3("Binormal", pick.mBinormal); + msg->sendMessage( object->getRegion()->getHost()); + + /* Diagnostic code + llinfos << "mUVCoords: " << pick.mUVCoords + << ", mSTCoords: " << pick.mSTCoords + << ", mObjectFace: " << pick.mObjectFace + << ", mIntersection: " << pick.mIntersection + << ", mNormal: " << pick.mNormal + << ", mBinormal: " << pick.mBinormal + << llendl; + + llinfos << "Avatar pos: " << gAgent.getPositionAgent() << llendl; + llinfos << "Object pos: " << object->getPosition() << llendl; + */ +} + + +void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick) +{ + if (!object) return; + + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ObjectDeGrab); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_LocalID, object->mLocalID); + msg->nextBlock("SurfaceInfo"); + msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); + msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); + msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); + msg->addVector3("Position", pick.mIntersection); + msg->addVector3("Normal", pick.mNormal); + msg->addVector3("Binormal", pick.mBinormal); + msg->sendMessage(object->getRegion()->getHost()); +} + + + diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index 61e3fcb8b2..06a3b662c8 100644 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -39,6 +39,13 @@ class LLTextBox; class LLViewerObject; class LLPickInfo; + +// Message utilities +void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, const LLVector3 &grab_offset); +void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick); + + + class LLToolGrab : public LLTool, public LLSingleton<LLToolGrab> { public: diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 2de7db38ed..2f60b6b90b 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -28,6 +28,8 @@ #include "lltranslate.h" +#include <curl/curl.h> + #include "llbufferstream.h" #include "llui.h" #include "llversioninfo.h" @@ -76,7 +78,9 @@ void LLTranslate::translateMessage(LLHTTPClient::ResponderPtr &result, const std //static void LLTranslate::getTranslateUrl(std::string &translate_url, const std::string &from_lang, const std::string &to_lang, const std::string &mesg) { - std::string escaped_mesg = curl_escape(mesg.c_str(), mesg.size()); + char * curl_str = curl_escape(mesg.c_str(), mesg.size()); + std::string const escaped_mesg(curl_str); + curl_free(curl_str); translate_url = m_GoogleURL + escaped_mesg + m_GoogleLangSpec diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index e06fe7bda0..93687dbd5f 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -80,6 +80,10 @@ void LLViewerChat::getChatColor(const LLChat& chat, LLColor4& r_color) { r_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor"); } + else if ( chat.mChatType == CHAT_TYPE_DIRECT ) + { + r_color = LLUIColorTable::instance().getColor("DirectChatColor"); + } else { r_color = LLUIColorTable::instance().getColor("ObjectChatColor"); @@ -146,6 +150,10 @@ void LLViewerChat::getChatColor(const LLChat& chat, std::string& r_color_name, F { r_color_name = "llOwnerSayChatColor"; } + else if ( chat.mChatType == CHAT_TYPE_DIRECT ) + { + r_color_name = "DirectChatColor"; + } else { r_color_name = "ObjectChatColor"; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 379bbe614d..87ca80260f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -57,6 +57,7 @@ #include "llworld.h" #include "pipeline.h" #include "llviewerjoystick.h" +#include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" #include "llparcel.h" #include "llkeyboard.h" @@ -183,6 +184,21 @@ static bool handleReleaseGLBufferChanged(const LLSD& newvalue) return true; } +static bool handleFSAASamplesChanged(const LLSD& newvalue) +{ + if (gPipeline.isInit()) + { + gPipeline.releaseGLBuffers(); + gPipeline.createGLBuffers(); + + if (LLPipeline::sRenderDeferred) + { + LLViewerShaderMgr::instance()->setShaders(); + } + } + return true; +} + static bool handleAnisotropicChanged(const LLSD& newvalue) { LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean(); @@ -357,6 +373,16 @@ static bool handleResetVertexBuffersChanged(const LLSD&) return true; } +static bool handleRepartition(const LLSD&) +{ + if (gPipeline.isInit()) + { + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gObjectList.repartitionObjects(); + } + return true; +} + static bool handleRenderDynamicLODChanged(const LLSD& newvalue) { LLPipeline::sDynamicLOD = newvalue.asBoolean(); @@ -560,6 +586,12 @@ void settings_setup_listeners() gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2)); gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2)); gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2)); + gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); + gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); @@ -568,7 +600,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); + gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleFSAASamplesChanged, _2)); gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2)); gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index e41773d273..f725f0fe86 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -582,6 +582,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM); const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); + gPipeline.processPartitionQ(); gPipeline.updateGeom(max_geom_update_time); stop_glerror(); } @@ -836,7 +837,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.bindTarget(); - glClearColor(0,0,0,0); + glClearColor(1,0,1,1); gPipeline.mDeferredScreen.clear(); } else @@ -995,8 +996,7 @@ void render_hud_attachments() S32 use_occlusion = LLPipeline::sUseOcclusion; LLPipeline::sUseOcclusion = 0; - LLPipeline::sDisableShaders = TRUE; - + //cull, sort, and render hud objects static LLCullResult result; LLSpatialGroup::sNoDelete = TRUE; @@ -1036,7 +1036,6 @@ void render_hud_attachments() gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } LLPipeline::sUseOcclusion = use_occlusion; - LLPipeline::sDisableShaders = FALSE; } glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 79c6c8db75..1e53274cd6 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -62,6 +62,7 @@ #include "llmutelist.h" #include "llpanelprofile.h" #include "llappviewer.h" +#include "lllogininstance.h" //#include "llfirstuse.h" #include "llwindow.h" @@ -2343,6 +2344,65 @@ BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask) } ////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::updateJavascriptObject() +{ + if ( mMediaSource ) + { + // flag to expose this information to internal browser or not. + bool expose_javascript_object = gSavedSettings.getBOOL("BrowserEnableJSObject"); + mMediaSource->jsExposeObjectEvent( expose_javascript_object ); + + // indicate if the values we have are valid (currently do this blanket-fashion for + // everything depending on whether you are logged in or not - this may require a + // more granular approach once variables are added that ARE valid before login + bool logged_in = LLLoginInstance::getInstance()->authSuccess(); + mMediaSource->jsValuesValidEvent( logged_in ); + + // current location within a region + LLVector3 agent_pos = gAgent.getPositionAgent(); + double x = agent_pos.mV[ VX ]; + double y = agent_pos.mV[ VY ]; + double z = agent_pos.mV[ VZ ]; + mMediaSource->jsAgentLocationEvent( x, y, z ); + + // current location within the grid + LLVector3d agent_pos_global = gAgent.getLastPositionGlobal(); + double global_x = agent_pos_global.mdV[ VX ]; + double global_y = agent_pos_global.mdV[ VY ]; + double global_z = agent_pos_global.mdV[ VZ ]; + mMediaSource->jsAgentGlobalLocationEvent( global_x, global_y, global_z ); + + // current agent orientation + double rotation = atan2( gAgent.getAtAxis().mV[VX], gAgent.getAtAxis().mV[VY] ); + double angle = rotation * RAD_TO_DEG; + if ( angle < 0.0f ) angle = 360.0f + angle; // TODO: has to be a better way to get orientation! + mMediaSource->jsAgentOrientationEvent( angle ); + + // current region agent is in + std::string region_name(""); + LLViewerRegion* region = gAgent.getRegion(); + if ( region ) + { + region_name = region->getName(); + }; + mMediaSource->jsAgentRegionEvent( region_name ); + + // language code the viewer is set to + mMediaSource->jsAgentLanguageEvent( LLUI::getLanguage() ); + + // maturity setting the agent has selected + if ( gAgent.prefersAdult() ) + mMediaSource->jsAgentMaturityEvent( "GMA" ); // Adult means see adult, mature and general content + else + if ( gAgent.prefersMature() ) + mMediaSource->jsAgentMaturityEvent( "GM" ); // Mature means see mature and general content + else + if ( gAgent.prefersPG() ) + mMediaSource->jsAgentMaturityEvent( "G" ); // PG means only see General content + } +} + +////////////////////////////////////////////////////////////////////////////////////////// std::string LLViewerMediaImpl::getName() const { if (mMediaSource) @@ -2640,6 +2700,9 @@ void LLViewerMediaImpl::update() { updateVolume(); + // TODO: this is updated every frame - is this bad? + updateJavascriptObject(); + // If we didn't just create the impl, it may need to get cookie updates. if(!sUpdatedCookies.empty()) { diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index e2e342cc45..a70c6f4887 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -339,7 +339,10 @@ public: LLVOVolume *getSomeObject(); void setUpdated(BOOL updated) ; BOOL isUpdated() ; - + + // updates the javascript object in the embedded browser with viewer values + void updateJavascriptObject(); + // Updates the "interest" value in this object void calculateInterest(); F64 getInterest() const { return mInterest; }; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2ed208bad1..41d8b57f36 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -106,6 +106,7 @@ #include "llappearancemgr.h" #include "lltrans.h" #include "lleconomy.h" +#include "lltoolgrab.h" #include "boost/unordered_map.hpp" using namespace LLVOAvatarDefines; @@ -2420,50 +2421,23 @@ class LLObjectEnableReportAbuse : public view_listener_t } }; + void handle_object_touch() { - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) return; - - LLPickInfo pick = LLToolPie::getInstance()->getPick(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return; - LLMessageSystem *msg = gMessageSystem; + LLPickInfo pick = LLToolPie::getInstance()->getPick(); - msg->newMessageFast(_PREHASH_ObjectGrab); - msg->nextBlockFast( _PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast( _PREHASH_ObjectData); - msg->addU32Fast( _PREHASH_LocalID, object->mLocalID); - msg->addVector3Fast(_PREHASH_GrabOffset, LLVector3::zero ); - msg->nextBlock("SurfaceInfo"); - msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); - msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); - msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); - msg->addVector3("Position", pick.mIntersection); - msg->addVector3("Normal", pick.mNormal); - msg->addVector3("Binormal", pick.mBinormal); - msg->sendMessage( object->getRegion()->getHost()); - - // *NOTE: Hope the packets arrive safely and in order or else - // there will be some problems. - // *TODO: Just fix this bad assumption. - msg->newMessageFast(_PREHASH_ObjectDeGrab); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_LocalID, object->mLocalID); - msg->nextBlock("SurfaceInfo"); - msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); - msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); - msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); - msg->addVector3("Position", pick.mIntersection); - msg->addVector3("Normal", pick.mNormal); - msg->addVector3("Binormal", pick.mBinormal); - msg->sendMessage(object->getRegion()->getHost()); + // *NOTE: Hope the packets arrive safely and in order or else + // there will be some problems. + // *TODO: Just fix this bad assumption. + send_ObjectGrab_message(object, pick, LLVector3::zero); + send_ObjectDeGrab_message(object, pick); } + + static void init_default_item_label(const std::string& item_name) { boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 37640ad0d4..b9293b3b31 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -107,9 +107,7 @@ class LLMeshUploadVisible : public view_listener_t { bool handleEvent(const LLSD& userdata) { - return gSavedSettings.getBOOL("MeshEnabled") && - LLViewerParcelMgr::getInstance()->allowAgentBuild() && - !gAgent.getRegion()->getCapability("ObjectAdd").empty(); + return gMeshRepo.meshUploadEnabled(); } }; @@ -1203,78 +1201,6 @@ void upload_new_resource( } } -BOOL upload_new_variable_price_resource( - const LLTransactionID &tid, - LLAssetType::EType asset_type, - std::string name, - std::string desc, - LLFolderType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perms, - U32 group_perms, - U32 everyone_perms, - const std::string& display_name, - const LLSD& asset_resources) -{ - LLAssetID uuid = - upload_new_resource_prep( - tid, - asset_type, - inv_type, - name, - display_name, - desc); - - llinfos << "*** Uploading: " << llendl; - llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl; - llinfos << "UUID: " << uuid << llendl; - llinfos << "Name: " << name << llendl; - llinfos << "Desc: " << desc << llendl; - lldebugs << "Folder: " - << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? (LLFolderType::EType)asset_type : destination_folder_type) << llendl; - lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; - - std::string url = gAgent.getRegion()->getCapability( - "NewFileAgentInventoryVariablePrice"); - - if ( !url.empty() ) - { - lldebugs - << "New Agent Inventory variable price upload" << llendl; - - // Each of the two capabilities has similar data, so - // let's reuse that code - - LLSD body; - - body = generate_new_resource_upload_capability_body( - asset_type, - name, - desc, - destination_folder_type, - inv_type, - next_owner_perms, - group_perms, - everyone_perms); - - body["asset_resources"] = asset_resources; - - LLHTTPClient::post( - url, - body, - new LLNewAgentInventoryVariablePriceResponder( - uuid, - asset_type, - body)); - - return TRUE; - } - else - { - return FALSE; - } -} - LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid) { if ( gDisconnected ) diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 1597821504..3136358b83 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -68,23 +68,6 @@ void upload_new_resource( S32 expected_upload_cost, void *userdata); -// TODO* : Move all uploads to use this new function -// since at some point, that upload path will be deprecated and no longer -// used - -// We make a new function here to ensure that previous code is not broken -BOOL upload_new_variable_price_resource( - const LLTransactionID& tid, - LLAssetType::EType type, - std::string name, - std::string desc, - LLFolderType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perms, - U32 group_perms, - U32 everyone_perms, - const std::string& display_name, - const LLSD& asset_resources); LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid); void increase_new_upload_stats(LLAssetType::EType asset_type); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 86b56df556..7ab335314a 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -96,7 +96,6 @@ #include "llviewerwindow.h" #include "llvlmanager.h" #include "llvoavatarself.h" -#include "llvotextbubble.h" #include "llworld.h" #include "pipeline.h" #include "llfloaterworldmap.h" @@ -3213,7 +3212,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) if (is_audible) { BOOL visible_in_chat_bubble = FALSE; - std::string verb; color.setVec(1.f,1.f,1.f,1.f); msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg); @@ -3262,18 +3260,19 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } else { + chat.mText = ""; switch(chat.mChatType) { case CHAT_TYPE_WHISPER: - verb = LLTrans::getString("whisper") + " "; + chat.mText = LLTrans::getString("whisper") + " "; break; case CHAT_TYPE_DEBUG_MSG: case CHAT_TYPE_OWNER: case CHAT_TYPE_NORMAL: - verb = ""; + case CHAT_TYPE_DIRECT: break; case CHAT_TYPE_SHOUT: - verb = LLTrans::getString("shout") + " "; + chat.mText = LLTrans::getString("shout") + " "; break; case CHAT_TYPE_START: case CHAT_TYPE_STOP: @@ -3281,13 +3280,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) break; default: LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL; - verb = ""; break; } - - chat.mText = ""; - chat.mText += verb; chat.mText += mesg; } @@ -4232,15 +4227,8 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) // Display green bubble on kill if ( gShowObjectUpdates ) { - LLViewerObject* newobject; - newobject = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, objectp->getRegion()); - - LLVOTextBubble* bubble = (LLVOTextBubble*) newobject; - - bubble->mColor.setVec(0.f, 1.f, 0.f, 1.f); - bubble->setScale( 2.0f * bubble->getScale() ); - bubble->setPositionGlobal(objectp->getPositionGlobal()); - gPipeline.addObject(bubble); + LLColor4 color(0.f,1.f,0.f,1.f); + gPipeline.addDebugBlip(objectp->getPositionAgent(), color); } // Do the kill @@ -4336,6 +4324,9 @@ void process_sound_trigger(LLMessageSystem *msg, void **) { return; } + + // Don't play sounds from gestures if they are not enabled. + if (!gSavedSettings.getBOOL("EnableGestureSounds")) return; gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global); } @@ -5376,10 +5367,10 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) { // notification was specified using the new mechanism, so we can just handle it here std::string notificationID; - msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
- if (!LLNotifications::getInstance()->templateExists(notificationID))
- {
- return false;
+ msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID); + if (!LLNotifications::getInstance()->templateExists(notificationID)) + { + return false; } std::string llsdRaw; @@ -6487,10 +6478,14 @@ void process_script_dialog(LLMessageSystem* msg, void**) LLSD payload; LLUUID object_id; - LLUUID owner_id; - msg->getUUID("Data", "ObjectID", object_id); - msg->getUUID("OwnerData", "OwnerID", owner_id); + +// For compability with OS grids first check for presence of extended packet before fetching data. + LLUUID owner_id; + if (gMessageSystem->getNumberOfBlocks("OwnerData") > 0) + { + msg->getUUID("OwnerData", "OwnerID", owner_id); + } if (LLMuteList::getInstance()->isMuted(object_id) || LLMuteList::getInstance()->isMuted(owner_id)) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6d493bfcd5..be9ff872c0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -89,7 +89,6 @@ #include "llvopartgroup.h" #include "llvosky.h" #include "llvosurfacepatch.h" -#include "llvotextbubble.h" #include "llvotree.h" #include "llvovolume.h" #include "llvowater.h" @@ -102,6 +101,7 @@ #include "lltrans.h" #include "llsdutil.h" #include "llmediaentry.h" +#include "llaccountingquota.h" //#define DEBUG_UPDATE_TYPE @@ -167,8 +167,6 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco // llwarns << "Creating new tree!" << llendl; // res = new LLVOTree(id, pcode, regionp); break; res = NULL; break; - case LL_PCODE_LEGACY_TEXT_BUBBLE: - res = new LLVOTextBubble(id, pcode, regionp); break; case LL_VO_CLOUDS: res = new LLVOClouds(id, pcode, regionp); break; case LL_VO_SURFACE_PATCH: @@ -1893,7 +1891,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // // - // WTF? If we're going to skip this message, why are we + // If we're going to skip this message, why are we // doing all the parenting, etc above? U32 packet_id = mesgsys->getCurrentRecvPacketID(); if (packet_id < mLatestRecvPacketID && @@ -1972,23 +1970,16 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, if ( gShowObjectUpdates ) { - if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->isSelf())) - && mRegionp) + LLColor4 color; + if (update_type == OUT_TERSE_IMPROVED) { - LLViewerObject* object = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, mRegionp); - LLVOTextBubble* bubble = (LLVOTextBubble*) object; - - if (update_type == OUT_TERSE_IMPROVED) - { - bubble->mColor.setVec(0.f, 0.f, 1.f, 1.f); - } - else - { - bubble->mColor.setVec(1.f, 0.f, 0.f, 1.f); - } - object->setPositionGlobal(getPositionGlobal()); - gPipeline.addObject(object); + color.setVec(0.f, 0.f, 1.f, 1.f); } + else + { + color.setVec(1.f, 0.f, 0.f, 1.f); + } + gPipeline.addDebugBlip(getPositionAgent(), color); } if ((0.0f == vel_mag_sq) && @@ -5282,7 +5273,7 @@ bool LLViewerObject::specialHoverCursor() const || (mClickAction != 0); } -void LLViewerObject::updateFlags() +void LLViewerObject::updateFlags(BOOL physics_changed) { LLViewerRegion* regionp = getRegion(); if(!regionp) return; @@ -5295,12 +5286,15 @@ void LLViewerObject::updateFlags() gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() ); gMessageSystem->addBOOL("IsPhantom", flagPhantom() ); gMessageSystem->addBOOL("CastsShadows", flagCastShadows() ); - gMessageSystem->nextBlock("ExtraPhysics"); - gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() ); - gMessageSystem->addF32("Density", getPhysicsDensity() ); - gMessageSystem->addF32("Friction", getPhysicsFriction() ); - gMessageSystem->addF32("Restitution", getPhysicsRestitution() ); - gMessageSystem->addF32("GravityMultiplier", getPhysicsGravity() ); + if (physics_changed) + { + gMessageSystem->nextBlock("ExtraPhysics"); + gMessageSystem->addU8("PhysicsShapeType", getPhysicsShapeType() ); + gMessageSystem->addF32("Density", getPhysicsDensity() ); + gMessageSystem->addF32("Friction", getPhysicsFriction() ); + gMessageSystem->addF32("Restitution", getPhysicsRestitution() ); + gMessageSystem->addF32("GravityMultiplier", getPhysicsGravity() ); + } gMessageSystem->sendReliable( regionp->getHost() ); } @@ -5699,3 +5693,10 @@ public: LLHTTPRegistration<ObjectPhysicsProperties> gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); + + +void LLViewerObject::updateQuota( const SelectionQuota& quota ) +{ + //update quotas + mSelectionQuota = quota; +} diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index e417343bec..a0ad52df6b 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -43,6 +43,7 @@ #include "v3dmath.h" #include "v3math.h" #include "llvertexbuffer.h" +#include "llaccountingquota.h" class LLAgent; // TODO: Get rid of this. class LLAudioSource; @@ -488,7 +489,7 @@ public: void setRegion(LLViewerRegion *regionp); virtual void updateRegion(LLViewerRegion *regionp); - void updateFlags(); + void updateFlags(BOOL physics_changed = FALSE); BOOL setFlags(U32 flag, BOOL state); void setPhysicsShapeType(U8 type); void setPhysicsGravity(F32 gravity); @@ -643,7 +644,11 @@ protected: void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id); void deleteParticleSource(); void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); - + +public: + void updateQuota( const SelectionQuota& quota ); + const SelectionQuota& getQuota( void ) { return mSelectionQuota; } + private: void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string void deleteTEImages(); // correctly deletes list of images @@ -705,6 +710,8 @@ protected: F32 mPhysicsCost; F32 mLinksetPhysicsCost; + SelectionQuota mSelectionQuota; + bool mCostStale; mutable bool mPhysicsShapeUnknown; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index ab2e07e4df..45c6777ae8 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1418,6 +1418,15 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id) mPendingObjectCost.erase(object_id); } +void LLViewerObjectList::updateQuota( const LLUUID& objectId, const SelectionQuota& quota ) +{ + LLViewerObject* pVO = findObject( objectId ); + if ( pVO ) + { + pVO->updateQuota( quota ); + } +} + void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object) { mStalePhysicsFlags.insert(object->getID()); @@ -1488,6 +1497,24 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) LLWorld::getInstance()->shiftRegions(offset); } +void LLViewerObjectList::repartitionObjects() +{ + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (!objectp->isDead()) + { + LLDrawable* drawable = objectp->mDrawable; + if (drawable && !drawable->isDead()) + { + drawable->updateBinRadius(); + drawable->updateSpatialExtents(); + drawable->movePartition(); + } + } + } +} + //debug code bool LLViewerObjectList::hasMapObjectInRegion(LLViewerRegion* regionp) { diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 65374bca70..9d1b5cb56f 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -36,6 +36,7 @@ // project includes #include "llviewerobject.h" +#include "llaccountingquota.h" class LLCamera; class LLNetMap; @@ -101,7 +102,10 @@ public: F32 restitution, F32 gravity_multiplier); + void updateQuota( const LLUUID& objectId, const SelectionQuota& costs ); + void shiftObjects(const LLVector3 &offset); + void repartitionObjects(); bool hasMapObjectInRegion(LLViewerRegion* regionp) ; void clearAllMapObjectsInRegion(LLViewerRegion* regionp) ; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 5ae4e872f3..8db72da1ee 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2202,9 +2202,9 @@ bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const = parcelOwner == (forGroup ? gAgent.getGroupID() : gAgent.getID()); bool isAuthorized - = (authorizeBuyer.isNull()
- || (gAgent.getID() == authorizeBuyer)
- || (gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_DEED)
+ = (authorizeBuyer.isNull() + || (gAgent.getID() == authorizeBuyer) + || (gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_DEED) && gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_SET_SALE_INFO))); return isForSale && !isOwner && isAuthorized && isEmpowered; diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index 45c9b3e91f..faa86d43dd 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -118,8 +118,8 @@ // Library includes from llvfs #include "lldir.h" -
-// Library includes from llmessage project
+ +// Library includes from llmessage project #include "llcachename.h" #endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index f835351c04..002e0567e4 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -69,6 +69,7 @@ #include "llspatialpartition.h" #include "stringize.h" #include "llviewercontrol.h" +#include "llsdserialize.h" #ifdef LL_WINDOWS #pragma warning(disable:4355) @@ -1140,6 +1141,20 @@ void LLViewerRegion::getInfo(LLSD& info) info["Region"]["Handle"]["y"] = (LLSD::Integer)y; } +void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) +{ + sim_features = mSimulatorFeatures; +} + +void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) +{ + std::stringstream str; + + LLSDSerialize::toPrettyXML(sim_features, str); + llinfos << str.str() << llendl; + mSimulatorFeatures = sim_features; +} + LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) { U32 local_id = objectp->getLocalID(); @@ -1480,6 +1495,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLSD capabilityNames = LLSD::emptyArray(); + capabilityNames.append("AccountingParcel"); + capabilityNames.append("AccountingSelection"); capabilityNames.append("AttachmentResources"); capabilityNames.append("AvatarPickerSearch"); capabilityNames.append("ChatSessionRequest"); @@ -1509,8 +1526,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); capabilityNames.append("NewFileAgentInventory"); - capabilityNames.append("NewFileAgentInventoryVariablePrice"); - capabilityNames.append("ObjectAdd"); capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelMediaURLFilterList"); capabilityNames.append("ParcelNavigateMedia"); @@ -1541,10 +1556,14 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("UpdateNotecardTaskInventory"); capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UploadBakedTexture"); - capabilityNames.append("UploadObjectAsset"); capabilityNames.append("ViewerMetrics"); capabilityNames.append("ViewerStartAuction"); capabilityNames.append("ViewerStats"); + //prep# Finalize these!!!!!!!!! + //capabilityNames.append("AccountingVO"); + capabilityNames.append("AccountingParcel"); + capabilityNames.append("AccountingRegion"); + // Please add new capabilities alphabetically to reduce // merge conflicts. @@ -1554,6 +1573,42 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLHTTPClient::post(url, capabilityNames, mImpl->mHttpResponderPtr); } +class SimulatorFeaturesReceived : public LLHTTPClient::Responder +{ + LOG_CLASS(SimulatorFeaturesReceived); +public: + SimulatorFeaturesReceived(LLViewerRegion* region) + : mRegion(region) + { } + + + void error(U32 statusNum, const std::string& reason) + { + LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL; + } + + void result(const LLSD& content) + { + if(!mRegion) //region is removed or responder is not created. + { + return ; + } + + mRegion->setSimulatorFeatures(content); + } + + static boost::intrusive_ptr<SimulatorFeaturesReceived> build( + LLViewerRegion* region) + { + return boost::intrusive_ptr<SimulatorFeaturesReceived>( + new SimulatorFeaturesReceived(region)); + } + +private: + LLViewerRegion* mRegion; +}; + + void LLViewerRegion::setCapability(const std::string& name, const std::string& url) { if(name == "EventQueueGet") @@ -1566,6 +1621,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u { LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url)); } + else if (name == "SimulatorFeatures") + { + // kick off a request for simulator features + LLHTTPClient::get(url, new SimulatorFeaturesReceived(this)); + } else { mImpl->mCapabilities[name] = url; @@ -1658,3 +1718,17 @@ std::string LLViewerRegion::getDescription() const { return stringize(*this); } + +bool LLViewerRegion::meshUploadEnabled() const +{ + return (mSimulatorFeatures.has("MeshUploadEnabled") && + mSimulatorFeatures["MeshUploadEnabled"].asBoolean()); +} + +bool LLViewerRegion::meshRezEnabled() const +{ + return (mSimulatorFeatures.has("MeshRezEnabled") && + mSimulatorFeatures["MeshRezEnabled"].asBoolean()); +} + + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 9c5b85b77f..3811b989e7 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -275,6 +275,12 @@ public: F32 getLandHeightRegion(const LLVector3& region_pos); void getInfo(LLSD& info); + + bool meshRezEnabled() const; + bool meshUploadEnabled() const; + + void getSimulatorFeatures(LLSD& info); + void setSimulatorFeatures(const LLSD& info); typedef enum { @@ -400,6 +406,8 @@ private: bool mCapabilitiesReceived; BOOL mReleaseNotesRequested; + + LLSD mSimulatorFeatures; }; inline BOOL LLViewerRegion::getAllowDamage() const diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 3e85802ba6..da4d0548d0 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -66,12 +66,20 @@ LLGLSLShader gObjectSimpleProgram; LLGLSLShader gObjectSimpleWaterProgram; LLGLSLShader gObjectFullbrightProgram; LLGLSLShader gObjectFullbrightWaterProgram; - LLGLSLShader gObjectFullbrightShinyProgram; LLGLSLShader gObjectFullbrightShinyWaterProgram; LLGLSLShader gObjectShinyProgram; LLGLSLShader gObjectShinyWaterProgram; +LLGLSLShader gObjectSimpleNonIndexedProgram; +LLGLSLShader gObjectSimpleNonIndexedWaterProgram; +LLGLSLShader gObjectFullbrightNonIndexedProgram; +LLGLSLShader gObjectFullbrightNonIndexedWaterProgram; +LLGLSLShader gObjectFullbrightShinyNonIndexedProgram; +LLGLSLShader gObjectFullbrightShinyNonIndexedWaterProgram; +LLGLSLShader gObjectShinyNonIndexedProgram; +LLGLSLShader gObjectShinyNonIndexedWaterProgram; + //object hardware skinning shaders LLGLSLShader gSkinnedObjectSimpleProgram; LLGLSLShader gSkinnedObjectFullbrightProgram; @@ -113,6 +121,7 @@ LLGLSLShader gDeferredImpostorProgram; LLGLSLShader gDeferredEdgeProgram; LLGLSLShader gDeferredWaterProgram; LLGLSLShader gDeferredDiffuseProgram; +LLGLSLShader gDeferredNonIndexedDiffuseProgram; LLGLSLShader gDeferredSkinnedDiffuseProgram; LLGLSLShader gDeferredSkinnedBumpProgram; LLGLSLShader gDeferredSkinnedAlphaProgram; @@ -132,13 +141,16 @@ LLGLSLShader gDeferredShadowProgram; LLGLSLShader gDeferredAvatarShadowProgram; LLGLSLShader gDeferredAttachmentShadowProgram; LLGLSLShader gDeferredAlphaProgram; +LLGLSLShader gDeferredAvatarEyesProgram; LLGLSLShader gDeferredFullbrightProgram; LLGLSLShader gDeferredGIProgram; LLGLSLShader gDeferredGIFinalProgram; LLGLSLShader gDeferredPostGIProgram; LLGLSLShader gDeferredPostProgram; LLGLSLShader gDeferredPostNoDoFProgram; - +LLGLSLShader gDeferredWLSkyProgram; +LLGLSLShader gDeferredWLCloudProgram; +LLGLSLShader gDeferredStarProgram; LLGLSLShader gLuminanceGatherProgram; @@ -160,6 +172,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gObjectFullbrightProgram); mShaderList.push_back(&gObjectFullbrightShinyProgram); mShaderList.push_back(&gObjectFullbrightShinyWaterProgram); + mShaderList.push_back(&gObjectSimpleNonIndexedProgram); + mShaderList.push_back(&gObjectFullbrightNonIndexedProgram); + mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram); + mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram); mShaderList.push_back(&gSkinnedObjectSimpleProgram); mShaderList.push_back(&gSkinnedObjectFullbrightProgram); mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); @@ -183,6 +199,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredAlphaProgram); mShaderList.push_back(&gDeferredSkinnedAlphaProgram); mShaderList.push_back(&gDeferredFullbrightProgram); + mShaderList.push_back(&gDeferredAvatarEyesProgram); mShaderList.push_back(&gDeferredPostGIProgram); mShaderList.push_back(&gDeferredEdgeProgram); mShaderList.push_back(&gDeferredPostProgram); @@ -190,6 +207,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredGIFinalProgram); mShaderList.push_back(&gDeferredWaterProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); + mShaderList.push_back(&gDeferredWLSkyProgram); + mShaderList.push_back(&gDeferredWLCloudProgram); + mShaderList.push_back(&gDeferredStarProgram); } LLViewerShaderMgr::~LLViewerShaderMgr() @@ -347,6 +367,10 @@ void LLViewerShaderMgr::setShaders() return; } + //setup preprocessor definitions + LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"))); + LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits); + reentrance = true; // Make sure the compiled shader map is cleared before we recompile shaders. @@ -577,6 +601,16 @@ void LLViewerShaderMgr::unloadShaders() gObjectFullbrightShinyWaterProgram.unload(); gObjectShinyWaterProgram.unload(); + gObjectSimpleNonIndexedProgram.unload(); + gObjectSimpleNonIndexedWaterProgram.unload(); + gObjectFullbrightNonIndexedProgram.unload(); + gObjectFullbrightNonIndexedWaterProgram.unload(); + + gObjectShinyNonIndexedProgram.unload(); + gObjectFullbrightShinyNonIndexedProgram.unload(); + gObjectFullbrightShinyNonIndexedWaterProgram.unload(); + gObjectShinyNonIndexedWaterProgram.unload(); + gSkinnedObjectSimpleProgram.unload(); gSkinnedObjectFullbrightProgram.unload(); gSkinnedObjectFullbrightShinyProgram.unload(); @@ -607,6 +641,7 @@ void LLViewerShaderMgr::unloadShaders() gPostNightVisionProgram.unload(); gDeferredDiffuseProgram.unload(); + gDeferredNonIndexedDiffuseProgram.unload(); gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); gDeferredSkinnedAlphaProgram.unload(); @@ -685,24 +720,35 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.clear(); 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] ) ); - shaders.push_back( make_pair( "windlight/transportF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "environment/waterFogF.glsl", mVertexShaderLevel[SHADER_WATER] ) ); - shaders.push_back( make_pair( "lighting/lightF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); - 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] ) ); + S32 ch = gGLManager.mNumTextureImageUnits-1; + + std::vector<S32> index_channels; + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT]) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/transportF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mVertexShaderLevel[SHADER_WATER] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); for (U32 i = 0; i < shaders.size(); i++) { // Note usage of GL_FRAGMENT_SHADER_ARB - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB) == 0) + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0) { return FALSE; } @@ -833,6 +879,9 @@ BOOL LLViewerShaderMgr::loadShadersEffects() { BOOL success = TRUE; + U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); + bool multisample = samples > 1 && LLPipeline::sRenderDeferred && gGLManager.mHasTextureMultisample; + if (mVertexShaderLevel[SHADER_EFFECT] == 0) { gGlowProgram.unload(); @@ -858,10 +907,21 @@ BOOL LLViewerShaderMgr::loadShadersEffects() if (success) { + std::string fragment; + + if (multisample) + { + fragment = "effects/glowExtractMSF.glsl"; + } + else + { + fragment = "effects/glowExtractF.glsl"; + } + gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; gGlowExtractProgram.mShaderFiles.clear(); gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowExtractProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms); if (!success) @@ -925,6 +985,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredTreeProgram.unload(); gDeferredDiffuseProgram.unload(); + gDeferredNonIndexedDiffuseProgram.unload(); gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); gDeferredSkinnedAlphaProgram.unload(); @@ -945,6 +1006,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.unload(); gDeferredAlphaProgram.unload(); gDeferredFullbrightProgram.unload(); + gDeferredAvatarEyesProgram.unload(); gDeferredPostGIProgram.unload(); gDeferredEdgeProgram.unload(); gDeferredPostProgram.unload(); @@ -952,6 +1014,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredGIProgram.unload(); gDeferredGIFinalProgram.unload(); gDeferredWaterProgram.unload(); + gDeferredWLSkyProgram.unload(); + gDeferredWLCloudProgram.unload(); + gDeferredStarProgram.unload(); return TRUE; } @@ -959,18 +1024,33 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() BOOL success = TRUE; + U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); + bool multisample = samples > 1 && gGLManager.mHasTextureMultisample; + if (success) { gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; gDeferredDiffuseProgram.mShaderFiles.clear(); gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits; gDeferredDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredDiffuseProgram.createShader(NULL, NULL); } if (success) { + gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; + gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); + gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredNonIndexedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL); + } + + + if (success) + { gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader"; gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true; gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); @@ -1000,9 +1080,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; + gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true; gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); } @@ -1039,40 +1120,83 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + std::string fragment; + + if (multisample) + { + fragment = "deferred/pointLightMSF.glsl"; + } + else + { + fragment = "deferred/pointLightF.glsl"; + } + gDeferredLightProgram.mName = "Deferred Light Shader"; gDeferredLightProgram.mShaderFiles.clear(); gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredLightProgram.createShader(NULL, NULL); } if (success) { + std::string fragment; + if (multisample) + { + fragment = "deferred/multiPointLightMSF.glsl"; + } + else + { + fragment = "deferred/multiPointLightF.glsl"; + } + gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader"; gDeferredMultiLightProgram.mShaderFiles.clear(); gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredMultiLightProgram.createShader(NULL, NULL); } if (success) { + std::string fragment; + + if (multisample) + { + fragment = "deferred/spotLightMSF.glsl"; + } + else + { + fragment = "deferred/multiSpotLightF.glsl"; + } + 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.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredSpotLightProgram.createShader(NULL, NULL); } if (success) { + std::string fragment; + + if (multisample) + { + fragment = "deferred/multiSpotLightMSF.glsl"; + } + else + { + fragment = "deferred/multiSpotLightF.glsl"; + } + 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.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); } @@ -1083,11 +1207,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (gSavedSettings.getBOOL("RenderDeferredSSAO")) { - fragment = "deferred/sunLightSSAOF.glsl"; + if (multisample) + { + fragment = "deferred/sunlightSSAOMSF.glsl"; + } + else + { + fragment = "deferred/sunLightSSAOF.glsl"; + } } else { - fragment = "deferred/sunLightF.glsl"; + if (multisample) + { + fragment = "deferred/sunlightMSF.glsl"; + } + else + { + fragment = "deferred/sunLightF.glsl"; + } } gDeferredSunProgram.mName = "Deferred Sun Shader"; @@ -1100,10 +1238,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + std::string fragment; + + if (multisample) + { + fragment = "deferred/blurLightMSF.glsl"; + } + else + { + fragment = "deferred/blurLightF.glsl"; + } + gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader"; gDeferredBlurLightProgram.mShaderFiles.clear(); gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredBlurLightProgram.createShader(NULL, NULL); } @@ -1116,6 +1265,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAlphaProgram.mFeatures.hasGamma = true; gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredAlphaProgram.mFeatures.hasLighting = true; + gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + if (mVertexShaderLevel[SHADER_DEFERRED] < 1) + { + gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits; + } + else + { //shave off some texture units for shadow maps + gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits - 6; + } + gDeferredAlphaProgram.mShaderFiles.clear(); gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1125,11 +1284,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; + gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; + gDeferredAvatarEyesProgram.mFeatures.hasTransport = true; + gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; + gDeferredAvatarEyesProgram.mShaderFiles.clear(); + gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarEyesProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarEyesProgram.createShader(NULL, NULL); + } + + if (success) + { gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader"; gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true; gDeferredFullbrightProgram.mFeatures.hasGamma = true; gDeferredFullbrightProgram.mFeatures.hasTransport = true; - gDeferredFullbrightProgram.mFeatures.isFullbright = true; + gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits; gDeferredFullbrightProgram.mShaderFiles.clear(); gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1153,10 +1326,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + std::string fragment; + + if (multisample) + { + fragment = "deferred/softenLightMSF.glsl"; + } + else + { + fragment = "deferred/softenLightF.glsl"; + } + gDeferredSoftenProgram.mName = "Deferred Soften Shader"; gDeferredSoftenProgram.mShaderFiles.clear(); gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; @@ -1230,41 +1414,106 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; gDeferredAvatarAlphaProgram.mShaderFiles.clear(); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms); } if (success) { + std::string fragment; + if (multisample) + { + fragment = "deferred/postDeferredMSF.glsl"; + } + else + { + fragment = "deferred/postDeferredF.glsl"; + } + 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.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredPostProgram.createShader(NULL, NULL); } if (success) { + std::string fragment; + if (multisample) + { + fragment = "deferred/postDeferredNoDoFMSF.glsl"; + } + else + { + fragment = "deferred/postDeferredNoDoFF.glsl"; + } + gDeferredPostNoDoFProgram.mName = "Deferred Post Shader"; gDeferredPostNoDoFProgram.mShaderFiles.clear(); gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredPostNoDoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); } + if (success) + { + gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; + //gWLSkyProgram.mFeatures.hasGamma = true; + gDeferredWLSkyProgram.mShaderFiles.clear(); + gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gDeferredWLSkyProgram.createShader(NULL, &mWLUniforms); + } + + if (success) + { + gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; + gDeferredWLCloudProgram.mShaderFiles.clear(); + gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gDeferredWLCloudProgram.createShader(NULL, &mWLUniforms); + } + + if (success) + { + gDeferredStarProgram.mName = "Deferred Star Program"; + gDeferredStarProgram.mShaderFiles.clear(); + gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gDeferredStarProgram.createShader(NULL, &mWLUniforms); + } + if (mVertexShaderLevel[SHADER_DEFERRED] > 1) { if (success) { + std::string fragment; + if (multisample) + { + fragment = "deferred/edgeMSF.glsl"; + } + else + { + fragment = "deferred/edgeF.glsl"; + } + 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.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredEdgeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredEdgeProgram.createShader(NULL, NULL); } @@ -1272,8 +1521,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (mVertexShaderLevel[SHADER_DEFERRED] > 2) { - - if (success) { gDeferredPostGIProgram.mName = "Deferred Post GI Shader"; @@ -1321,7 +1568,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() BOOL LLViewerShaderMgr::loadShadersObject() { BOOL success = TRUE; - + if (mVertexShaderLevel[SHADER_OBJECT] == 0) { gObjectShinyProgram.unload(); @@ -1332,6 +1579,14 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectSimpleWaterProgram.unload(); gObjectFullbrightProgram.unload(); gObjectFullbrightWaterProgram.unload(); + gObjectShinyNonIndexedProgram.unload(); + gObjectFullbrightShinyNonIndexedProgram.unload(); + gObjectFullbrightShinyNonIndexedWaterProgram.unload(); + gObjectShinyNonIndexedWaterProgram.unload(); + gObjectSimpleNonIndexedProgram.unload(); + gObjectSimpleNonIndexedWaterProgram.unload(); + gObjectFullbrightNonIndexedProgram.unload(); + gObjectFullbrightNonIndexedWaterProgram.unload(); gSkinnedObjectSimpleProgram.unload(); gSkinnedObjectFullbrightProgram.unload(); gSkinnedObjectFullbrightShinyProgram.unload(); @@ -1346,12 +1601,144 @@ BOOL LLViewerShaderMgr::loadShadersObject() if (success) { + gObjectSimpleNonIndexedProgram.mName = "Non indexed Shader"; + gObjectSimpleNonIndexedProgram.mFeatures.calculatesLighting = true; + gObjectSimpleNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true; + gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true; + gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectSimpleNonIndexedProgram.mShaderFiles.clear(); + gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader"; + gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesLighting = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.hasLighting = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader"; + gObjectFullbrightNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightNonIndexedProgram.mFeatures.hasGamma = true; + gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true; + gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true; + gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightNonIndexedProgram.mShaderFiles.clear(); + gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightNonIndexedWaterProgram.mName = "Non Indexed Fullbright Water Shader"; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader"; + gObjectShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectShinyNonIndexedProgram.mFeatures.calculatesLighting = true; + gObjectShinyNonIndexedProgram.mFeatures.hasGamma = true; + gObjectShinyNonIndexedProgram.mFeatures.hasAtmospherics = true; + gObjectShinyNonIndexedProgram.mFeatures.isShiny = true; + gObjectShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectShinyNonIndexedProgram.mShaderFiles.clear(); + gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gObjectShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); + } + + if (success) + { + gObjectShinyNonIndexedWaterProgram.mName = "Non Indexed Shiny Water Shader"; + gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesLighting = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.isShiny = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); + } + + if (success) + { + gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader"; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.isFullbright = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.isShiny = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasGamma = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear(); + gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); + } + + if (success) + { + gObjectFullbrightShinyNonIndexedWaterProgram.mName = "Non Indexed Fullbright Shiny Water Shader"; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isShiny = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasGamma = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); + } + + if (success) + { gObjectSimpleProgram.mName = "Simple Shader"; gObjectSimpleProgram.mFeatures.calculatesLighting = true; gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; gObjectSimpleProgram.mFeatures.hasGamma = true; gObjectSimpleProgram.mFeatures.hasAtmospherics = true; gObjectSimpleProgram.mFeatures.hasLighting = true; + gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0; gObjectSimpleProgram.mShaderFiles.clear(); gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1367,6 +1754,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; gObjectSimpleWaterProgram.mFeatures.hasLighting = true; + gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0; gObjectSimpleWaterProgram.mShaderFiles.clear(); gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1382,6 +1770,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightProgram.mFeatures.hasGamma = true; gObjectFullbrightProgram.mFeatures.hasTransport = true; gObjectFullbrightProgram.mFeatures.isFullbright = true; + gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0; gObjectFullbrightProgram.mShaderFiles.clear(); gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1396,6 +1785,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightWaterProgram.mFeatures.isFullbright = true; gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; gObjectFullbrightWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0; gObjectFullbrightWaterProgram.mShaderFiles.clear(); gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1412,6 +1802,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectShinyProgram.mFeatures.hasGamma = true; gObjectShinyProgram.mFeatures.hasAtmospherics = true; gObjectShinyProgram.mFeatures.isShiny = true; + gObjectShinyProgram.mFeatures.mIndexedTextureChannels = 0; gObjectShinyProgram.mShaderFiles.clear(); gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1427,6 +1818,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectShinyWaterProgram.mFeatures.isShiny = true; gObjectShinyWaterProgram.mFeatures.hasWaterFog = true; gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true; + gObjectShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0; gObjectShinyWaterProgram.mShaderFiles.clear(); gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1443,6 +1835,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightShinyProgram.mFeatures.isShiny = true; gObjectFullbrightShinyProgram.mFeatures.hasGamma = true; gObjectFullbrightShinyProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = 0; gObjectFullbrightShinyProgram.mShaderFiles.clear(); gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1459,6 +1852,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0; gObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1478,6 +1872,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true; gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true; gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectSimpleProgram.mShaderFiles.clear(); gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1493,6 +1888,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true; gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true; gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectFullbrightProgram.mShaderFiles.clear(); gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1509,6 +1905,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true; gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true; gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear(); gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1525,6 +1922,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true; gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true; gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true; + gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectShinySimpleProgram.mShaderFiles.clear(); gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1540,9 +1938,11 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true; gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear(); gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1559,6 +1959,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true; gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true; gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear(); gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1577,6 +1978,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true; gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1595,6 +1997,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true; gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true; gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear(); gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1635,6 +2038,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarProgram.mFeatures.hasGamma = true; gAvatarProgram.mFeatures.hasAtmospherics = true; gAvatarProgram.mFeatures.hasLighting = true; + gAvatarProgram.mFeatures.disableTextureIndex = true; gAvatarProgram.mShaderFiles.clear(); gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1650,6 +2054,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarWaterProgram.mFeatures.hasWaterFog = true; gAvatarWaterProgram.mFeatures.hasAtmospherics = true; gAvatarWaterProgram.mFeatures.hasLighting = true; + gAvatarWaterProgram.mFeatures.disableTextureIndex = true; gAvatarWaterProgram.mShaderFiles.clear(); gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1670,6 +2075,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() { gAvatarPickProgram.mName = "Avatar Pick Shader"; gAvatarPickProgram.mFeatures.hasSkinning = true; + gAvatarPickProgram.mFeatures.disableTextureIndex = true; gAvatarPickProgram.mShaderFiles.clear(); gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB)); gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1686,6 +2092,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarEyeballProgram.mFeatures.hasGamma = true; gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; gAvatarEyeballProgram.mFeatures.hasLighting = true; + gAvatarEyeballProgram.mFeatures.disableTextureIndex = true; gAvatarEyeballProgram.mShaderFiles.clear(); gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB)); gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 72ac5e02ee..6ecba65470 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -298,16 +298,25 @@ extern LLVector4 gShinyOrigin; //object shaders extern LLGLSLShader gObjectSimpleProgram; extern LLGLSLShader gObjectSimpleWaterProgram; +extern LLGLSLShader gObjectSimpleNonIndexedProgram; +extern LLGLSLShader gObjectSimpleNonIndexedWaterProgram; extern LLGLSLShader gObjectFullbrightProgram; extern LLGLSLShader gObjectFullbrightWaterProgram; +extern LLGLSLShader gObjectFullbrightNonIndexedProgram; +extern LLGLSLShader gObjectFullbrightNonIndexedWaterProgram; extern LLGLSLShader gObjectSimpleLODProgram; extern LLGLSLShader gObjectFullbrightLODProgram; extern LLGLSLShader gObjectFullbrightShinyProgram; extern LLGLSLShader gObjectFullbrightShinyWaterProgram; +extern LLGLSLShader gObjectFullbrightShinyNonIndexedProgram; +extern LLGLSLShader gObjectFullbrightShinyNonIndexedWaterProgram; + extern LLGLSLShader gObjectShinyProgram; extern LLGLSLShader gObjectShinyWaterProgram; +extern LLGLSLShader gObjectShinyNonIndexedProgram; +extern LLGLSLShader gObjectShinyNonIndexedWaterProgram; extern LLGLSLShader gSkinnedObjectSimpleProgram; extern LLGLSLShader gSkinnedObjectFullbrightProgram; @@ -349,6 +358,7 @@ extern LLGLSLShader gDeferredImpostorProgram; extern LLGLSLShader gDeferredEdgeProgram; extern LLGLSLShader gDeferredWaterProgram; extern LLGLSLShader gDeferredDiffuseProgram; +extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; extern LLGLSLShader gDeferredSkinnedDiffuseProgram; extern LLGLSLShader gDeferredSkinnedBumpProgram; extern LLGLSLShader gDeferredSkinnedAlphaProgram; @@ -373,8 +383,11 @@ extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAttachmentShadowProgram; extern LLGLSLShader gDeferredAlphaProgram; extern LLGLSLShader gDeferredFullbrightProgram; +extern LLGLSLShader gDeferredAvatarEyesProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; - +extern LLGLSLShader gDeferredWLSkyProgram; +extern LLGLSLShader gDeferredWLCloudProgram; +extern LLGLSLShader gDeferredStarProgram; extern LLGLSLShader gLuminanceGatherProgram; //current avatar shader parameter pointer diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index af06421bf9..4da0f80a00 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1168,6 +1168,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mSavedRawDiscardLevel = -1 ; mDesiredSavedRawDiscardLevel = -1 ; mLastReferencedSavedRawImageTime = 0.0f ; + mKeptSavedRawImageTime = 0.f ; mLastCallBackActiveTime = 0.f; } @@ -2696,8 +2697,16 @@ void LLViewerFetchedTexture::saveRawImage() mLastReferencedSavedRawImageTime = sCurrentTime ; } -void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard) +void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_time) { + mKeptSavedRawImageTime = kept_time ; + mLastReferencedSavedRawImageTime = sCurrentTime ; + + if(mSavedRawDiscardLevel > -1 && mSavedRawDiscardLevel <= desired_discard) + { + return ; //raw imge is ready. + } + if(!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard) { mForceToSaveRawImage = TRUE ; @@ -2713,11 +2722,16 @@ void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard) mRawImage = NULL ; mRawDiscardLevel = INVALID_DISCARD_LEVEL ; - } + } } } void LLViewerFetchedTexture::destroySavedRawImage() { + if(mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime) + { + return ; //keep the saved raw image. + } + mForceToSaveRawImage = FALSE ; mSaveRawImage = FALSE ; @@ -2729,6 +2743,7 @@ void LLViewerFetchedTexture::destroySavedRawImage() mSavedRawDiscardLevel = -1 ; mDesiredSavedRawDiscardLevel = -1 ; mLastReferencedSavedRawImageTime = 0.0f ; + mKeptSavedRawImageTime = 0.f ; } LLImageRaw* LLViewerFetchedTexture::getSavedRawImage() diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index d512f8ec3a..c5b8c8923a 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -465,7 +465,7 @@ public: S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;} BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;} BOOL isRawImageValid()const { return mIsRawImageValid ; } - void forceToSaveRawImage(S32 desired_discard = 0) ; + void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; void destroySavedRawImage() ; LLImageRaw* getSavedRawImage() ; @@ -550,6 +550,7 @@ protected: S32 mSavedRawDiscardLevel; S32 mDesiredSavedRawDiscardLevel; F32 mLastReferencedSavedRawImageTime ; + F32 mKeptSavedRawImageTime ; //a small version of the copy of the raw image (<= 64 * 64) LLPointer<LLImageRaw> mCachedRawImage; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d9ff931575..a1d9434d44 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -89,16 +89,14 @@ LLViewerTextureList::LLViewerTextureList() } void LLViewerTextureList::init() -{ +{ sRenderThreadID = LLThread::currentID() ; - mInitialized = TRUE ; sNumImages = 0; + mUpdateStats = TRUE; mMaxResidentTexMemInMegaBytes = 0; mMaxTotalTextureMemInMegaBytes = 0 ; - mUpdateStats = TRUE; - // Update how much texture RAM we're allowed to use. updateMaxResidentTexMem(0); // 0 = use current @@ -110,8 +108,8 @@ void LLViewerTextureList::doPreloadImages() { LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL; - llassert_always(mInitialized) ;
- llassert_always(mImageList.empty()) ;
+ llassert_always(mInitialized) ; + llassert_always(mImageList.empty()) ; llassert_always(mUUIDMap.empty()) ; // Set the "missing asset" image @@ -283,6 +281,8 @@ void LLViewerTextureList::shutdown() mUUIDMap.clear(); mImageList.clear(); + + mInitialized = FALSE ; //prevent loading textures again. } void LLViewerTextureList::dump() @@ -330,6 +330,11 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& LLGLenum primary_format, const LLUUID& force_id) { + if(!mInitialized) + { + return NULL ; + } + std::string full_path = gDirUtilp->findSkinnedFilename("textures", filename); if (full_path.empty()) { @@ -350,6 +355,11 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& LLGLenum primary_format, const LLUUID& force_id) { + if(!mInitialized) + { + return NULL ; + } + // generate UUID based on hash of filename LLUUID new_id; if (force_id.notNull()) @@ -409,6 +419,11 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, LLGLenum primary_format, LLHost request_from_host) { + if(!mInitialized) + { + return NULL ; + } + // Return the image with ID image_id // If the image is not found, creates new image and // enqueues a request for transmission diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 6fe79c2e85..b1441cc281 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -601,7 +601,7 @@ public: ypos += y_inc; - if (gSavedSettings.getBOOL("MeshEnabled")) + if (gMeshRepo.meshRezEnabled()) { addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f))); @@ -1638,6 +1638,7 @@ LLViewerWindow::LLViewerWindow( gSavedSettings.setBOOL("RenderVBOEnable", FALSE); } LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); + LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ec2b5a4c98..1b53348b43 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -56,6 +56,7 @@ #include "lleditingmotion.h" #include "llemote.h" //#include "llfirstuse.h" +#include "llfloatertools.h" #include "llheadrotmotion.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" @@ -1541,7 +1542,35 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e return TRUE; } } + + if (isSelf()) + { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = (*attachment_iter); + + if (attached_object && !attached_object->isDead() && attachment->getValid()) + { + LLDrawable* drawable = attached_object->mDrawable; + if (drawable->isState(LLDrawable::RIGGED)) + { //regenerate octree for rigged attachment + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); + } + } + } + } + } } + + LLVector3 position; if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position)) @@ -1557,6 +1586,56 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e return FALSE; } +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, + S32 face, + BOOL pick_transparent, + S32* face_hit, + LLVector3* intersection, + LLVector2* tex_coord, + LLVector3* normal, + LLVector3* bi_normal) +{ + if (isSelf() && !gAgent.needsRenderAvatar()) + { + return NULL; + } + + LLViewerObject* hit = NULL; + + if (lineSegmentBoundingBox(start, end)) + { + LLVector3 local_end = end; + LLVector3 local_intersection; + + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = (*attachment_iter); + + if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal)) + { + local_end = local_intersection; + if (intersection) + { + *intersection = local_intersection; + } + + hit = attached_object; + } + } + } + } + + return hit; +} + //----------------------------------------------------------------------------- // parseSkeletonFile() //----------------------------------------------------------------------------- @@ -4968,19 +5047,6 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name ) //----------------------------------------------------------------------------- void LLVOAvatar::resetJointPositionsToDefault( void ) { - const LLVector3& avPos = getCharacterPosition(); - - //Reposition the pelvis - LLJoint* pPelvis = mRoot.findJoint("mPelvis"); - if ( pPelvis ) - { - pPelvis->setPosition( avPos + pPelvis->getPosition() ); - } - else - { - llwarns<<"Can't get pelvis joint."<<llendl; - return; - } //Subsequent joints are relative to pelvis for( S32 i = 0; i < (S32)mNumJoints; ++i ) @@ -4991,7 +5057,7 @@ void LLVOAvatar::resetJointPositionsToDefault( void ) pJoint->setId( LLUUID::null ); //restore joints to default positions, however skip over the pelvis - if ( pJoint && pPelvis != pJoint ) + if ( pJoint ) { pJoint->restoreOldXform(); } @@ -6017,7 +6083,7 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) LLVOVolume* pVObj = pVO->mDrawable->getVOVolume(); if ( pVObj ) { - const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() ); + const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj ); if ( pSkinData ) { const int jointCnt = pSkinData->mJointNames.size(); @@ -6028,6 +6094,14 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) if ( bindCnt > 0 ) { LLVOAvatar::resetJointPositionsToDefault(); + //Need to handle the repositioning of the cam, updating rig data etc during outfit editing + //This handles the case where we detach a replacement rig. + if ( gAgentCamera.cameraCustomizeAvatar() ) + { + gAgent.unpauseAnimation(); + //Still want to refocus on head bone + gAgentCamera.changeCameraToCustomizeAvatar(); + } } } } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 295799fd24..03c0498a2a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -145,6 +145,14 @@ public: LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point LLVector3* normal = NULL, // return the surface normal at the intersection point LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point + LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, + S32 face = -1, // which face to check, -1 = ALL_SIDES + BOOL pick_transparent = FALSE, + S32* face_hit = NULL, // which face was hit + LLVector3* intersection = NULL, // return the intersection point + LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point + LLVector3* normal = NULL, // return the surface normal at the intersection point + LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point //-------------------------------------------------------------------- // LLCharacter interface and related diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index b888a263d0..f0b5b50feb 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -76,6 +76,7 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) S32 size = -1; BOOL success; + mDP.assignBuffer(mBuffer, 0); success = check_read(apr_file, &mLocalID, sizeof(U32)); if(success) { @@ -136,10 +137,7 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) LLVOCacheEntry::~LLVOCacheEntry() { - if(mBuffer) - { - delete[] mBuffer; - } + mDP.freeBuffer(); } @@ -285,8 +283,6 @@ LLVOCache::~LLVOCache() void LLVOCache::setDirNames(ELLPath location) { - std::string delem = gDirUtilp->getDirDelimiter(); - mHeaderFileName = gDirUtilp->getExpandedFilename(location, object_cache_dirname, header_filename); mObjectCacheDirName = gDirUtilp->getExpandedFilename(location, object_cache_dirname); } @@ -339,8 +335,7 @@ void LLVOCache::removeCache(ELLPath location) llinfos << "about to remove the object cache due to settings." << llendl ; - std::string delem = gDirUtilp->getDirDelimiter(); - std::string mask = delem + "*"; + std::string mask = "*"; std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname); llinfos << "Removing cache at " << cache_dir << llendl; gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files @@ -361,8 +356,7 @@ void LLVOCache::removeCache() llinfos << "about to remove the object cache due to some error." << llendl ; - std::string delem = gDirUtilp->getDirDelimiter(); - std::string mask = delem + "*"; + std::string mask = "*"; llinfos << "Removing cache at " << mObjectCacheDirName << llendl; gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask); diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index 78aa6e6ab8..478708cd78 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -244,9 +244,13 @@ void LLVOClouds::getGeometry(S32 te, vtx[2] = puff_pos_agent + right + up; vtx[3] = puff_pos_agent + right - up; + verticesp->mV[3] = 0.f; *verticesp++ = vtx[0]; + verticesp->mV[3] = 0.f; *verticesp++ = vtx[1]; + verticesp->mV[3] = 0.f; *verticesp++ = vtx[2]; + verticesp->mV[3] = 0.f; *verticesp++ = vtx[3]; *texcoordsp++ = uvs[0]; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 6f354b78b1..a4b0910c92 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -324,10 +324,18 @@ void LLVOPartGroup::getGeometry(S32 idx, LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis(); - + + //HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should) + // this works because there is actually a 4th float stored after the vertex position which is used as a texture index + // also, somebody please VECTORIZE THIS + + verticesp->mV[3] = 0.f; *verticesp++ = part_pos_agent + up - right; + verticesp->mV[3] = 0.f; *verticesp++ = part_pos_agent - up - right; + verticesp->mV[3] = 0.f; *verticesp++ = part_pos_agent + up + right; + verticesp->mV[3] = 0.f; *verticesp++ = part_pos_agent - up + right; *colorsp++ = part.mColor; @@ -360,7 +368,7 @@ U32 LLVOPartGroup::getPartitionType() const } LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_STREAM_DRAW_ARB) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; @@ -418,6 +426,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co mFaceList.push_back(facep); vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); + llassert(facep->getIndicesCount() < 65536); } obj->mDepth /= count; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 6396bc042d..800af26b69 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1483,6 +1483,8 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons facep->setVertexBuffer(buff); } + llassert(facep->getVertexBuffer()->getNumIndices() == 6); + index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp); if (-1 == index_offset) diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index dbcd4f50ca..510525259f 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -375,6 +375,8 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, S32 num_vertices, num_indices; U32 index; + llassert(mLastStride > 0); + render_stride = mLastStride; patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); S32 vert_size = patch_size / render_stride; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 8946d4e0b6..3c7fe708e6 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -980,11 +980,6 @@ void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices, for (S32 i = 0; i < index_count; i++) { U16 index = index_offset + i; - if (idx[index] >= vert_start + vert_count || - idx[index] < vert_start) - { - llerrs << "WTF?" << llendl; - } *indices++ = idx[index]-vert_start+cur_idx; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e9a8c9b80a..c5e2c56e4b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -73,6 +73,7 @@ #include "llagent.h" #include "llviewermediafocus.h" #include "lldatapacker.h" +#include "llviewershadermgr.h" #include "llvoavatar.h" #include "llvocache.h" @@ -1095,8 +1096,6 @@ void LLVOVolume::updateSculptTexture() } - - void LLVOVolume::notifyMeshLoaded() { mSculptChanged = TRUE; @@ -1222,7 +1221,7 @@ BOOL LLVOVolume::calcLOD() } //hold onto unmodified distance for debugging - F32 debug_distance = distance; + //F32 debug_distance = distance; distance *= sDistanceFactor; @@ -1245,7 +1244,9 @@ BOOL LLVOVolume::calcLOD() if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO)) { - setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); + //setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); + + setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex())); } if (cur_detail != mLOD) @@ -1274,6 +1275,15 @@ BOOL LLVOVolume::updateLOD() gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); mLODChanged = TRUE; } + else + { + F32 new_radius = getBinRadius(); + F32 old_radius = mDrawable->getBinRadius(); + if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f) + { + gPipeline.markPartitionMove(mDrawable); + } + } lod_changed = lod_changed || LLViewerObject::updateLOD(); @@ -3086,16 +3096,28 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes) { + F32 radius = getScale().length(); + if (isMesh()) { LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID()); - F32 radius = getScale().length(); - return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD); } - - return 0.f; + else + { + LLVolume* volume = getVolume(); + S32 counts[4]; + LLVolume::getLoDTriangleCounts(volume->getParams(), counts); + + LLSD header; + header["lowest_lod"]["size"] = counts[0] * 10; + header["low_lod"]["size"] = counts[1] * 10; + header["medium_lod"]["size"] = counts[2] * 10; + header["high_lod"]["size"] = counts[3] * 10; + + return LLMeshRepository::getStreamingCost(header, radius); + } } U32 LLVOVolume::getTriangleCount() @@ -3187,6 +3209,10 @@ F32 LLVOVolume::getBinRadius() F32 scale = 1.f; + S32 size_factor = llmax(gSavedSettings.getS32("OctreeStaticObjectSizeFactor"), 1); + S32 attachment_size_factor = llmax(gSavedSettings.getS32("OctreeAttachmentSizeFactor"), 1); + LLVector3 distance_factor = gSavedSettings.getVector3("OctreeDistanceFactor"); + LLVector3 alpha_distance_factor = gSavedSettings.getVector3("OctreeAlphaDistanceFactor"); const LLVector4a* ext = mDrawable->getSpatialExtents(); BOOL shrink_wrap = mDrawable->isAnimating(); @@ -3216,6 +3242,8 @@ F32 LLVOVolume::getBinRadius() radius = llmin(bounds.mV[1], bounds.mV[2]); radius = llmin(radius, bounds.mV[0]); radius *= 0.5f; + radius *= 1.f+mDrawable->mDistanceWRTCamera*alpha_distance_factor[1]; + radius += mDrawable->mDistanceWRTCamera*alpha_distance_factor[0]; } else if (shrink_wrap) { @@ -3226,24 +3254,19 @@ F32 LLVOVolume::getBinRadius() } else if (mDrawable->isStatic()) { - /*if (mDrawable->getRadius() < 2.0f) - { - radius = 16.f; - } - else - { - radius = llmax(mDrawable->getRadius(), 32.f); - }*/ - - radius = (((S32) mDrawable->getRadius())/2+1)*8; + radius = llmax((S32) mDrawable->getRadius(), 1)*size_factor; + radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1]; + radius += mDrawable->mDistanceWRTCamera * distance_factor[0]; } else if (mDrawable->getVObj()->isAttachment()) { - radius = (((S32) (mDrawable->getRadius()*4)+1))*2; + radius = llmax((S32) mDrawable->getRadius(),1)*attachment_size_factor; } else { - radius = 8.f; + radius = mDrawable->getRadius(); + radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1]; + radius += mDrawable->mDistanceWRTCamera * distance_factor[0]; } return llclamp(radius*scale, 0.5f, 256.f); @@ -3342,7 +3365,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf()) { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); + updateRiggedVolume(); + genBBoxes(FALSE); volume = mRiggedVolume; transform = false; } @@ -3521,7 +3545,7 @@ void LLVOVolume::updateRiggedVolume() LLVolume* volume = getVolume(); - const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID()); + const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID(), this); if (!skin) { @@ -3712,6 +3736,21 @@ LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) mSlopRatio = 0.25f; } +bool can_batch_texture(LLFace* facep) +{ + if (facep->getTextureEntry()->getBumpmap()) + { //bump maps aren't worked into texture batching yet + return false; + } + + if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) + { //texture animation breaks batches + return false; + } + + return true; +} + void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -3762,12 +3801,36 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerTexture* tex = facep->getTexture(); + U8 index = facep->getTextureIndex(); + + bool batchable = false; + + if (index < 255 && idx >= 0) + { + if (index < draw_vec[idx]->mTextureList.size()) + { + if (draw_vec[idx]->mTextureList[index].isNull()) + { + batchable = true; + draw_vec[idx]->mTextureList[index] = tex; + } + else if (draw_vec[idx]->mTextureList[index] == tex) + { //this face's texture index can be used with this batch + batchable = true; + } + } + else + { //texture list can be expanded to fit this texture index + batchable = true; + } + } + U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255); if (idx >= 0 && draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && - (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) && + (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) && #if LL_DARWIN draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && @@ -3781,6 +3844,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); + + if (index >= draw_vec[idx]->mTextureList.size()) + { + draw_vec[idx]->mTextureList.resize(index+1); + draw_vec[idx]->mTextureList[index] = tex; + } draw_vec[idx]->validate(); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]); @@ -3811,6 +3880,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mDrawMode = LLRender::TRIANGLE_STRIP; } + if (index < 255) + { //initialize texture list for texture batching + draw_info->mTextureList.resize(index+1); + draw_info->mTextureList[index] = tex; + } draw_info->validate(); } } @@ -3910,7 +3984,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOVolume* vobj = drawablep->getVOVolume(); - if (vobj->getVolume() && vobj->getVolume()->isTetrahedron()) + if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled())) { continue; } @@ -3923,7 +3997,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool rigged = vobj->isAttachment() && vobj->isMesh() && - gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID()); + gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); @@ -3965,7 +4039,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if ( pAvatarVO ) { LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); - const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId ); + const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); if ( pSkinData ) { @@ -4233,15 +4307,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; - if (LLPipeline::sRenderDeferred) + bool batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; + + if (batch_textures) { bump_mask |= LLVertexBuffer::MAP_BINORMAL; + genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE); + genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE); + genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE); + genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE); + } + else + { + genDrawInfo(group, simple_mask, simple_faces); + genDrawInfo(group, fullbright_mask, fullbright_faces); + genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE); + genDrawInfo(group, alpha_mask, alpha_faces, TRUE); } - genDrawInfo(group, simple_mask, simple_faces); - genDrawInfo(group, bump_mask, bump_faces); - genDrawInfo(group, fullbright_mask, fullbright_faces); - genDrawInfo(group, alpha_mask, alpha_faces, TRUE); if (!LLPipeline::sDelayVBUpdate) { @@ -4297,11 +4380,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) face->getGeometryVolume(*volume, face->getTEOffset(), vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); } - - if (!face) - { - llerrs << "WTF?" << llendl; - } } drawablep->clearState(LLDrawable::REBUILD_ALL); @@ -4356,13 +4434,37 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - if (group && group->isState(LLSpatialGroup::NEW_DRAWINFO)) + llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); +} + +struct CompareBatchBreakerModified +{ + bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) { - llerrs << "WTF?" << llendl; + const LLTextureEntry* lte = lhs->getTextureEntry(); + const LLTextureEntry* rte = rhs->getTextureEntry(); + + if (lte->getBumpmap() != rte->getBumpmap()) + { + return lte->getBumpmap() < rte->getBumpmap(); + } + else if (lte->getFullbright() != rte->getFullbright()) + { + return lte->getFullbright() < rte->getFullbright(); + } + else if (lte->getGlow() != rte->getGlow()) + { + return lte->getGlow() < rte->getGlow(); + } + else + { + return lhs->getTexture() < rhs->getTexture(); + } + } -} +}; -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures) { //calculate maximum number of vertices to store in a single buffer U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); @@ -4371,7 +4473,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!distance_sort) { //sort faces by things that break batches - std::sort(faces.begin(), faces.end(), LLFace::CompareBatchBreaker()); + std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); } else { @@ -4391,6 +4493,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: buffer_index = -1; } + S32 texture_index_channels = gGLManager.mNumTextureImageUnits-1; //always reserve one for shiny for now just for simplicity + + if (LLPipeline::sRenderDeferred && distance_sort) + { + texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; + } + + texture_index_channels = llmin(texture_index_channels, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")); + + while (face_iter != faces.end()) { //pull off next face @@ -4421,24 +4533,101 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: std::vector<LLFace*>::iterator i = face_iter; ++i; - while (i != faces.end() && - (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) + std::vector<LLViewerTexture*> texture_list; + + if (batch_textures) { - facep = *i; - - if (geom_count + facep->getGeomCount() > max_vertices) - { //cut batches on geom count too big - break; + U8 cur_tex = 0; + facep->setTextureIndex(cur_tex); + texture_list.push_back(tex); + + //if (can_batch_texture(facep)) + { + while (i != faces.end()) + { + facep = *i; + if (facep->getTexture() != tex) + { + if (distance_sort) + { //textures might be out of order, see if texture exists in current batch + bool found = false; + for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) + { + if (facep->getTexture() == texture_list[tex_idx]) + { + cur_tex = tex_idx; + found = true; + break; + } + } + + if (!found) + { + cur_tex = texture_list.size(); + } + } + else + { + cur_tex++; + } + + if (!can_batch_texture(facep)) + { //face is bump mapped or has an animated texture matrix -- can't + //batch more than 1 texture at a time + break; + } + + if (cur_tex >= texture_index_channels) + { //cut batches when index channels are depleted + break; + } + + tex = facep->getTexture(); + + texture_list.push_back(tex); + } + + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big + break; + } + + ++i; + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); + + facep->setTextureIndex(cur_tex); + } } - ++i; - index_count += facep->getIndicesCount(); - geom_count += facep->getGeomCount(); + tex = texture_list[0]; + } + else + { + while (i != faces.end() && + (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) + { + facep = *i; + + + //face has no texture index + facep->mDrawInfo = NULL; + facep->setTextureIndex(255); + + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big + break; + } + + ++i; + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); + } } //create/delete/resize vertex buffer if needed LLVertexBuffer* buffer = NULL; - LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(tex); + LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter); if (found_iter != group->mBufferMap[mask].end()) { @@ -4469,7 +4658,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } } - buffer_map[mask][tex].push_back(buffer); + buffer_map[mask][*face_iter].push_back(buffer); //add face geometry @@ -4483,6 +4672,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: facep->setGeomIndex(index_offset); facep->setVertexBuffer(buffer); + if (batch_textures && facep->getTextureIndex() == 255) + { + llerrs << "Invalid texture index." << llendl; + } + { //for debugging, set last time face was updated vs moved facep->updateRebuildFlags(); @@ -4495,12 +4689,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: U32 te_idx = facep->getTEOffset(); - if (facep->getGeometryVolume(*volume, te_idx, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) - { - buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), - facep->getIndicesStart(), facep->getIndicesCount()); - } + facep->getGeometryVolume(*volume, te_idx, + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset); } } @@ -4681,7 +4871,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun { vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); - + llassert(facep->getIndicesCount() < 65536); //remember face (for sorting) mFaceList.push_back(facep); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f64eb89866..e74bf2a620 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -392,6 +392,7 @@ void LLPipeline::init() { LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT); + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); @@ -580,11 +581,6 @@ void LLPipeline::allocatePhysicsBuffer() if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY) { mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - if (mSampleBuffer.getWidth() == mPhysicsDisplay.getWidth() && - mSampleBuffer.getHeight() == mPhysicsDisplay.getHeight()) - { - mPhysicsDisplay.setSampleBuffer(&mSampleBuffer); - } } } @@ -594,8 +590,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) mScreenWidth = resX; mScreenHeight = resY; - //never use more than 4 samples for render targets - U32 samples = llmin(gSavedSettings.getU32("RenderFSAASamples"), (U32) 4); + //cap samples at 4 for render targets to avoid out of memory errors + U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); + if (gGLManager.mIsATI) { //disable multisampling of render targets where ATI is involved samples = 0; @@ -621,16 +618,22 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED); //allocate deferred rendering color buffers - mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); + mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); addDeferredAttachments(mDeferredScreen); - mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); + +#if LL_DARWIN + // As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO + mEdgeMap.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +#else mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +#endif 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); + mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); } else { @@ -639,7 +642,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) if (ssao) { //only need mDeferredLight[1] for ssao - mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false); } else { @@ -648,10 +651,15 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) if (gi) { //only need mDeferredLight[2] and mGIMapPost for gi - mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false); for (U32 i = 0; i < 2; i++) { +#if LL_DARWIN + // As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO + mGIMapPost[i].allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +#else mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +#endif } } else @@ -666,8 +674,12 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); +#if LL_DARWIN + U32 shadow_fmt = 0; +#else //HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug) U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0; +#endif if (shadow_detail > 0) { //allocate 4 sun shadow maps @@ -729,35 +741,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); } - if (LLRenderTarget::sUseFBO && samples > 1) - { - mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); - if (LLPipeline::sRenderDeferred) - { - addDeferredAttachments(mSampleBuffer); - mDeferredScreen.setSampleBuffer(&mSampleBuffer); - mEdgeMap.setSampleBuffer(&mSampleBuffer); - } - - mScreen.setSampleBuffer(&mSampleBuffer); - - stop_glerror(); - } - else - { - mSampleBuffer.release(); - } - if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets mDeferredScreen.shareDepthBuffer(mScreen); - 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]); - } - } } gGL.getTexUnit(0)->disable(); @@ -787,16 +773,7 @@ void LLPipeline::updateRenderDeferred() //static void LLPipeline::refreshRenderDeferred() { - if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) - { - //turn the deferred rendering and glow off when draw physics shapes. - sRenderDeferred = FALSE ; - sRenderGlow = FALSE ; - } - else - { - updateRenderDeferred() ; - } + updateRenderDeferred(); } void LLPipeline::releaseGLBuffers() @@ -826,7 +803,6 @@ void LLPipeline::releaseGLBuffers() mScreen.release(); mPhysicsDisplay.release(); mUIScreen.release(); - mSampleBuffer.release(); mDeferredScreen.release(); mDeferredDepth.release(); for (U32 i = 0; i < 3; i++) @@ -2535,6 +2511,32 @@ void LLPipeline::markGLRebuild(LLGLUpdate* glu) } } +void LLPipeline::markPartitionMove(LLDrawable* drawable) +{ + if (!drawable->isState(LLDrawable::PARTITION_MOVE) && + !drawable->getPositionGroup().equals3(LLVector4a::getZero())) + { + drawable->setState(LLDrawable::PARTITION_MOVE); + mPartitionQ.push_back(drawable); + } +} + +void LLPipeline::processPartitionQ() +{ + for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) + { + LLDrawable* drawable = *iter; + if (!drawable->isDead()) + { + drawable->updateBinRadius(); + drawable->movePartition(); + } + drawable->clearState(LLDrawable::PARTITION_MOVE); + } + + mPartitionQ.clear(); +} + void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -3595,7 +3597,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) if (gDebugGL) { check_stack_depth(stack_depth); - std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); + std::string msg = llformat("pass %d", i); LLGLState::checkStates(msg); LLGLState::checkTextureChannels(msg); LLGLState::checkClientArrays(msg); @@ -4070,6 +4072,37 @@ void LLPipeline::renderDebug() bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); + if (!hud_only && !mDebugBlips.empty()) + { //render debug blips + glPointSize(8.f); + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + + gGL.begin(LLRender::POINTS); + for (std::list<DebugBlip>::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); ) + { + DebugBlip& blip = *iter; + + blip.mAge += gFrameIntervalSeconds; + if (blip.mAge > 2.f) + { + mDebugBlips.erase(iter++); + } + else + { + iter++; + } + + blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f; + + gGL.color4fv(blip.mColor.mV); + gGL.vertex3fv(blip.mPosition.mV); + } + gGL.end(); + gGL.flush(); + glPointSize(1.f); + } + + // Debug stuff. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5904,7 +5937,6 @@ LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) return NULL; } - void LLPipeline::resetVertexBuffers(LLDrawable* drawable) { if (!drawable || drawable->isDead()) @@ -6050,7 +6082,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) { LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM); if (!(gPipeline.canUseVertexShaders() && - sRenderGlow)) + sRenderGlow) || + (!sRenderDeferred && hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))) { return; } @@ -6096,67 +6129,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.setColorMask(true, true); glClearColor(0,0,0,0); - - /*if (for_snapshot) - { - gGL.getTexUnit(0)->bind(&mGlow[1]); - { - //LLGLEnable stencil(GL_STENCIL_TEST); - //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); - //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - //LLGLDisable blend(GL_BLEND); - - // If the snapshot is constructed from tiles, calculate which - // tile we're in. - - //from LLViewerCamera::setPerpsective - if (zoom_factor > 1.f) - { - int pos_y = subfield / llceil(zoom_factor); - int pos_x = subfield - (pos_y*llceil(zoom_factor)); - F32 size = 1.f/zoom_factor; - - tc1.set(pos_x*size, pos_y*size); - tc2 = tc1 + LLVector2(size,size); - } - else - { - tc2.set(1,1); - } - - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_ADD); - - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.color4f(1,1,1,1); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,1); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(1,-1); - - gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); - gGL.vertex2f(1,1); - - gGL.end(); - - gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - - gGL.flush(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - return; - }*/ - + { { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); @@ -6180,11 +6153,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->disable(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); - gGL.getTexUnit(0)->bind(&mScreen); - + mScreen.bindTexture(0, 0); + gGL.color4f(1,1,1,1); gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); gGL.begin(LLRender::TRIANGLE_STRIP); @@ -6199,7 +6169,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.end(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbind(mScreen.getUsage()); mGlow[2].flush(); } @@ -6227,7 +6197,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) for (S32 i = 0; i < kernel; i++) { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); mGlow[i%2].bindTarget(); @@ -6288,9 +6257,9 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) LLVertexBuffer::unbind(); - if (LLPipeline::sRenderDeferred && !LLViewerCamera::getInstance()->cameraUnderWater()) + if (LLPipeline::sRenderDeferred) { - bool dof_enabled = true; + bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater(); LLGLSLShader* shader = &gDeferredPostProgram; if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) @@ -6298,7 +6267,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) shader = &gDeferredGIFinalProgram; dof_enabled = false; } - else if (LLToolMgr::getInstance()->inBuildMode() || !gSavedSettings.getBOOL("RenderDepthOfField")) + else if (!dof_enabled || LLToolMgr::getInstance()->inBuildMode() || !gSavedSettings.getBOOL("RenderDepthOfField")) { //squish focal length when in build mode (or if DoF is disabled) so DoF doesn't make editing objects difficult shader = &gDeferredPostNoDoFProgram; dof_enabled = false; @@ -6420,11 +6389,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) shader->uniform1f("magnification", magnification); } - S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); if (channel > -1) { mScreen.bindTexture(0, channel); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); } //channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); //if (channel > -1) @@ -6517,6 +6485,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) { + gGL.setColorMask(true, false); + LLVector2 tc1(0,0); LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, (F32) gViewerWindow->getWorldViewHeightRaw()*2); @@ -6563,25 +6533,23 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen noise_map = mNoiseMap; } - LLGLState::checkTextureChannels(); - shader.bind(); S32 channel = 0; - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(0,channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(1, channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(2, channel); @@ -6704,22 +6672,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen 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); - }*/ + stop_glerror(); - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage()); if (channel > -1) { 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); + //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(); @@ -6748,7 +6710,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen stop_glerror(); - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[light_index].getUsage()); if (channel > -1) { mDeferredLight[light_index].bindTexture(0, channel); @@ -6968,9 +6930,9 @@ void LLPipeline::renderDeferredLighting() } //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); + LLGLDisable stencil(GL_STENCIL_TEST); + //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); + //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); gGL.setColorMask(true, true); @@ -7772,33 +7734,41 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) LLViewerTexture* img = volume->getLightTexture(); + if (img == NULL) + { + img = LLViewerFetchedTexture::sWhiteImagep; + } + S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); - if (channel > -1 && img) + if (channel > -1) { - gGL.getTexUnit(channel)->bind(img); + if (img) + { + gGL.getTexUnit(channel)->bind(img); - F32 lod_range = logf(img->getWidth())/logf(2.f); + F32 lod_range = logf(img->getWidth())/logf(2.f); - shader.uniform1f("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)); + 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(); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); - 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_NORMAL, mDeferredScreen.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[0].getUsage()); 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_EDGE, mEdgeMap.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, mDeferredLight[1].getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, mDeferredLight[2].getUsage()); shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIP); @@ -7845,8 +7815,6 @@ 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) @@ -9394,6 +9362,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadow[i+4].flush(); } } + else + { //no spotlight shadows + mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; + } + if (!gSavedSettings.getBOOL("CameraOffset")) { @@ -9816,4 +9789,9 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...) } } +void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) +{ + DebugBlip blip(position, color); + mDebugBlips.push_back(blip); +} diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e9a250cd6d..e9da25e544 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -157,7 +157,8 @@ public: void markGLRebuild(LLGLUpdate* glu); void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); - + void markPartitionMove(LLDrawable* drawablep); + //get the object between start and end that's closest to start. LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, BOOL pick_transparent, @@ -211,6 +212,7 @@ public: 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 processPartitionQ(); void updateGeom(F32 max_dtime); void updateGL(); void rebuildPriorityGroups(); @@ -358,6 +360,8 @@ public: static void updateRenderDeferred(); static void refreshRenderDeferred(); + void addDebugBlip(const LLVector3& position, const LLColor4& color); + private: void unloadShaders(); void addToQuickLookup( LLDrawPool* new_poolp ); @@ -524,7 +528,6 @@ public: LLRenderTarget mEdgeMap; LLRenderTarget mDeferredDepth; LLRenderTarget mDeferredLight[3]; - LLMultisampleBuffer mSampleBuffer; LLRenderTarget mGIMap; LLRenderTarget mGIMapPost[2]; LLRenderTarget mLuminanceMap; @@ -637,6 +640,9 @@ protected: LLDrawable::drawable_list_t mBuildQ2; // non-priority LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + + LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius + bool mGroupQ2Locked; bool mGroupQ1Locked; @@ -726,6 +732,20 @@ public: protected: std::vector<LLFace*> mSelectedFaces; + class DebugBlip + { + public: + LLColor4 mColor; + LLVector3 mPosition; + F32 mAge; + + DebugBlip(const LLVector3& position, const LLColor4& color) + : mColor(color), mPosition(position), mAge(0.f) + { } + }; + + std::list<DebugBlip> mDebugBlips; + LLPointer<LLViewerFetchedTexture> mFaceSelectImagep; U32 mLightMask; diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index d02662681b..973df6998a 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -760,7 +760,7 @@ <color name="MenuBarProjectBgColor" reference="MdBlue" /> - + <color name="MeshImportTableNormalColor" value="1 1 1 1"/> @@ -768,6 +768,9 @@ name="MeshImportTableHighlightColor" value="0.2 0.8 1 1"/> + <color + name="DirectChatColor" + reference="LtOrange" /> <!-- Generic color names (legacy) --> <color diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 09105c1d28..09105c1d28 100644..100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index 651d803e0d..d480b63094 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -178,6 +178,8 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para request["uri"] = uri; request["reply"] = replyPump.getName(); rewrittenURIs = postAndWait(self, request, srv_pump_name, filter); + // EXP-772: If rewrittenURIs fail, try original URI as a fallback. + rewrittenURIs.append(uri); } // we no longer need the filter LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction")); |