diff options
396 files changed, 11115 insertions, 5013 deletions
@@ -72,7 +72,6 @@ b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3 b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3 b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release -92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start 3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work 63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start 4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release @@ -81,7 +80,6 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release b53a0576eec80614d7767ed72b40ed67aeff27c9 2.5.2-release 92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start -f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start 4e9eec6a347f89b2b3f295beb72f1cf7837dff66 2.6.0-start 9283d6d1d7eb71dfe4c330e7c9144857e7356bde 2.6.0-beta1 9283d6d1d7eb71dfe4c330e7c9144857e7356bde DRTVWR-40_2.6.0-beta1 @@ -111,6 +109,36 @@ d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1 5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start -11d5d8080e67c3955914caf98f2eb116af30e55a 2.6.9-start +beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1 +beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1 11d5d8080e67c3955914caf98f2eb116af30e55a 2.6.9-start e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start +77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-57_2.6.9-beta1 +77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-beta1 +be2000b946f8cb3de5f44b2d419287d4c48ec4eb DRTVWR-54_2.6.8-release +be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release +dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release +dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release +8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release +8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release +77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-56_2.6.9-release +8835e0e3c0d3a48244c287bc05811dfc2fba43ec 2.7.0-start +43c7ee846b7eed80786acbbf35d03bd016a3e85d DRTVWR-59_2.7.0-beta1 +43c7ee846b7eed80786acbbf35d03bd016a3e85d 2.7.0-beta1 +77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-release +54fd44ac92e4c61435ea33effe093a3527e18d98 2.7.1-start +0c4d0c24278074f219e5a32e72b449e78301d11b DRTVWR-61_2.7.1-beta1 +0c4d0c24278074f219e5a32e72b449e78301d11b 2.7.1-beta1 +8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release +8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release +77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-56_2.6.9-release +9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start +e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1 +e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1 +6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start +6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start +77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-release +a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release +a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release +e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1 +e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1 diff --git a/BuildParams b/BuildParams index 0a193803da..2e0e74ab70 100644 --- a/BuildParams +++ b/BuildParams @@ -69,8 +69,7 @@ viewer-pre-release.viewer_channel = "Second Life Release" viewer-pre-release.login_channel = "Second Life Release" viewer-pre-release.build_debug_release_separately = true viewer-pre-release.build_viewer_update_version_manager = true -#viewer-pre-release.release-viewer.jira = DRTVWR-13 -viewer-pre-release.release-viewer.jira = DRTVWR-46 +#viewer-pre-release.release-viewer.jira = DRTVWR-46 # ======================================= @@ -103,6 +102,16 @@ mesh-development.build_CYGWIN_Debug = false mesh-development.build_viewer_update_version_manager = false # ======================================== +# mesh-asset-deprecation +# ======================================== +mesh-asset-deprecation.viewer_channel = "Project Viewer - Mesh Asset Deprecation" +mesh-asset-deprecation.login_channel = "Project Viewer - Mesh Asset Deprecation" +mesh-asset-deprecation.viewer_grid = aditi +mesh-asset-deprecation.build_debug_release_separately = true +mesh-asset-deprecation.build_CYGWIN_Debug = false +mesh-asset-deprecation.build_viewer_update_version_manager = false + +# ======================================== # viewer-mesh # ======================================== @@ -142,24 +151,12 @@ gooey.viewer_grid = agni gooey.build_viewer_update_version_manager = false # ======================================== -# Display Names project +# Search Project # ======================================== -#viewer-identity-evolution.email = leyla@lindenlab.com -viewer-identity.build_Debug = false -viewer-identity.build_RelWithDebInfo = false -viewer-identity.build_viewer = true -viewer-identity.build_server = false -viewer-identity.build_server_tests = false -viewer-identity.build_Linux = true -viewer-identity.build_hg_bundle = true -viewer-identity.bulld_docs = true -viewer-identity.viewer_channel = "Second Life Project Viewer" -viewer-identity.login_channel = "Second Life Project Viewer" -viewer-identity.viewer_grid = aditi -viewer-identity.build_viewer_update_version_manager = false - - +search_project-viewer.build_debug_release_separately = true +search_project-viewer.viewer_channel = "Second Life Project Viewer - Search" +search_project-viewer.login_channel = "Second Life Project Viewer - Search" # ======================================== # palange @@ -190,9 +187,10 @@ oz_viewer-devreview.build_debug_release_separately = true oz_project-1.build_debug_release_separately = true oz_project-2.build_debug_release_separately = true oz-project-3.build_debug_release_separately = true - - oz_viewer-beta-review.build_debug_release_separately = true +oz_viewer-poreview.build_debug_release_separately = true +oz_viewer-poreview.codeticket_add_context = false + # ======================================== # enus # ======================================== diff --git a/autobuild.xml b/autobuild.xml index d908344df9..63701dae79 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -18,9 +18,9 @@ <key>archive</key> <map> <key>hash</key> - <string>7c546f54f6ed654f713c778af3925dd4</string> + <string>b2fe1c860613a68e74d4384be418ffee</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/226566/arch/Darwin/installer/glod-1.0pre4-darwin-20110413.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Darwin/installer/glod-1.0pre4-darwin-20110610.tar.bz2</string> </map> <key>name</key> <string>darwin</string> @@ -30,9 +30,9 @@ <key>archive</key> <map> <key>hash</key> - <string>18c708163d2a669bc3c030b05b4ebe61</string> + <string>c0c64dae149d0892343e2ff300fd06b9</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/226657/arch/Linux/installer/glod-1.0pre4-linux-20110414.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Linux/installer/glod-1.0pre4-linux-20110611.tar.bz2</string> </map> <key>name</key> <string>linux</string> @@ -42,9 +42,9 @@ <key>archive</key> <map> <key>hash</key> - <string>c4ae6cddc04e0b2908a301726a53922c</string> + <string>842208365f5b108dac4c7c733b99da9c</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/226194/arch/CYGWIN/installer/glod-1.0pre4-windows-20110408.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/CYGWIN/installer/glod-1.0pre4-windows-20110610.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -1206,9 +1206,9 @@ <key>archive</key> <map> <key>hash</key> - <string>76c1015eafcba5ca9932c3009533b51c</string> + <string>82798d0da3ac3d97c91517a575d9ea1c</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/225273/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20110329.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/231093/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20110526.tar.bz2</string> </map> <key>name</key> <string>darwin</string> @@ -1230,9 +1230,9 @@ <key>archive</key> <map> <key>hash</key> - <string>1b1b8e104e39c542d69eb37b5ee81818</string> + <string>f0708d18943a05013493f69ab7dc6429</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/225249/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20110329.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/231093/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20110526.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -1290,9 +1290,9 @@ <key>archive</key> <map> <key>hash</key> - <string>c81bacf922bb3b540d92b660364c48ce</string> + <string>9bf7a96c1d2fadb180fda91740c945c6</string> <key>url</key> - <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-0.2-20101013.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-libndofdev-linux/rev/233137/arch/Linux/installer/libndofdev-0.3-linux-20110617.tar.bz2</string> </map> <key>name</key> <string>linux</string> @@ -1524,7 +1524,7 @@ <key>hash</key> <string>bb0abe962b3b8208ed2dab0424aab33d</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-pcre/rev/228822/arch/Linux/installer/pcre-7.6-linux-20110504.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-pcre/rev/228822/arch/Linux/installer/pcre-7.6-linux-20110504.tar.bz2</string> </map> <key>name</key> <string>linux</string> diff --git a/doc/contributions.txt b/doc/contributions.txt index dfbccb5a6c..b744f4db3e 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -76,6 +76,7 @@ Aleric Inglewood VWR-13996 VWR-14426 VWR-24247 + VWR-25654 VWR-24251 VWR-24252 VWR-24254 @@ -209,6 +210,7 @@ Boroondas Gupte STORM-1182 VWR-233 VWR-20583 + VWR-25654 VWR-20891 VWR-23455 VWR-24487 @@ -440,6 +442,10 @@ Jonathan Yap STORM-1095 STORM-1236 STORM-1259 + STORM-787 + STORM-1313 + STORM-899 + STORM-1273 Kage Pixel VWR-11 Ken March @@ -849,6 +855,7 @@ Twisted Laws STORM-844 STORM-643 STORM-954 + STORM-1103 Vadim Bigbear VWR-2681 Vector Hastings 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/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/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/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/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")); diff --git a/install.xml b/install.xml deleted file mode 100644 index 889386b336..0000000000 --- a/install.xml +++ /dev/null @@ -1,1851 +0,0 @@ -<?xml version="1.0" ?> -<llsd> -<map> - <key>installables</key> - <map> - <key>GL</key> - <map> - <key>copyright</key> - <string>Copyright (c) 1991-2000 Silicon Graphics, Inc.</string> - <key>description</key> - <string>A standard for 3D Graphics rendering engine.</string> - <key>license</key> - <string>GL</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>0bd2795a2afe09f6c563f2f888f24cc9</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/GL-darwin-20080613.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>2ab29212a7f3acdaebf10059af816be0</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/GL-linux-20080812.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>9c3dff3817f1105f9054401fdef1fe50</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/GL-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>91155239b02f576384603795d41eb971</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/GL-windows-20090505.tar.bz2</uri> - </map> - </map> - </map> - <key>SDL</key> - <map> - <key>copyright</key> - <string>Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga</string> - <key>description</key> - <string>The Simple DirectMedia Layer libraries are used for handling input and basic window/GL setup on the Linux client. Packages also include cursors.</string> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>fce0ff7d2cdf0f36c1647e6a3916e29e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/SDL-1.2.12-linux-20090218.tar.bz2</uri> - </map> - </map> - </map> - <key>apr_suite</key> - <map> - <key>license</key> - <string>apache 2.0</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>115d8ac44a91efdb173e9b3e478c46b6</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.3.7-darwin-20090805.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>7b84cd6a3c601a104d9c09e58ef2f50c</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.2.8-linux-20080812.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>1a7e1186855d48d8316ce86803095f70</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.2.8-linux64-20080909a.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>a02619c1e30a3db02d3883bf1ad7a1e6</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.3.8-windows-20090911.tar.bz2</uri> - </map> - </map> - </map> - <key>ares</key> - <map> - <key>copyright</key> - <string>Copyright 1998 by the Massachusetts Institute of Technology.</string> - <key>description</key> - <string>Performs DNS requests and name resolves asynchronously. Used with libcurl to keep all HTTP operations async.</string> - <key>license</key> - <string>c-ares</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>cdb2f5c4a5a1f9ecd75bc1dbdd4db8e9</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ares-1.7.1-darwin-20100606.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>91694429e391efeea1de974df26032a2</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ares-1.7.1-linux-20100527.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>c4242416e0b2e642c0bf062a19a250e4</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ares-1.3.0-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>4b84738eec2e21b0c096d53b79ee2681</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ares-1.7.1-windows-20100611a.tar.bz2</uri> - </map> - </map> - </map> - <key>artwork-common</key> - <map> - <key>copyright</key> - <string>(C) 2008 Linden Research, Inc.</string> - <key>description</key> - <string>Second Life(TM) Viewer Artwork</string> - <key>license</key> - <string>artwork</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>5e047437d73d1017bf270a6c6e936f23</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/artwork-common-20090415.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>5e047437d73d1017bf270a6c6e936f23</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/artwork-common-20090415.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>5e047437d73d1017bf270a6c6e936f23</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/artwork-common-20090415.tar.bz2</uri> - </map> - </map> - </map> - <key>berkeley</key> - <map> - <key>copyright</key> - <string>Copyright (c) 1990-1999 Sleepycat Software. All rights reserved.</string> - <key>description</key> - <string>a high-performance, embedded database library</string> - <key>license</key> - <string>sleepycat</string> - </map> - <key>boost</key> - <map> - <key>copyright</key> - <string>various</string> - <key>description</key> - <string>A set of portable C++ libraries which provide a wide set of functionality. </string> - <key>license</key> - <string>boost</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>71defd179827bf172b76d6020023e0e8</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.39.0-darwin-20100222a.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>4db3d74e40d149eeec06f4d97a609bb1</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.39.0-linux-20100624.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>af4badd6b2c10bc4db82ff1256695892</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.39.0-linux64-20100119.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>72e6e2eff5d146a107f3059b6c31fb95</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.39.0-windows-20100630.tar.bz2</uri> - </map> - </map> - </map> - <key>curl</key> - <map> - <key>copyright</key> - <string>Copyright (c) 1996 - 2008, Daniel Stenberg, <daniel@haxx.se>.</string> - <key>description</key> - <string>Client-side URL transfer library. Handles moving data across the net in many different protocols. Used to GET/POST/PUT/DELETE web resources. </string> - <key>license</key> - <string>curl</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>ca8f0134fa5ab6f34a6eeb8d0896c9b0</string> - <key>url</key> - <uri>https://s3.amazonaws.com/automated-builds-secondlife-com/hg/repo/brad_curl-autobuild/rev/216961/arch/Darwin/installer/curl-7.21.1-darwin-20101214.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>9c9b629b62bf874d550c430ad678dc04</string> - <key>url</key> - <uri>https://s3.amazonaws.com/automated-builds-secondlife-com/hg/repo/brad_curl-autobuild/rev/216961/arch/Linux/installer/curl-7.21.1-linux-20101215.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>6994192cea7ab2d885a158a3de474273</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/curl-7.16.4a-linux64-20090303.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>48691883065a82d53691d73aae81d4c1</string> - <key>url</key> - <uri>https://s3.amazonaws.com/automated-builds-secondlife-com/hg/repo/brad_curl-autobuild/rev/216961/arch/CYGWIN/installer/curl-7.21.1-windows-20101214.tar.bz2</uri> - </map> - </map> - </map> - <key>dbghelp</key> - <map> - <key>copyright</key> - <string>Copyright Microsoft Corporation</string> - <key>description</key> - <string>dbghelp: Debug helper from Microsoft Debugging Tools For Windows</string> - <key>license</key> - <string>MSDTW</string> - <key>packages</key> - <map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>b7563064037e032143ca2d610aae5153</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/dbghelp-6.11.1.404-windows-20090520.tar.bz2</uri> - </map> - </map> - </map> - <key>dbusglib</key> - <map> - <key>copyright</key> - <string>Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.</string> - <key>description</key> - <string>dbus/dbus-glib: headers only</string> - <key>license</key> - <string>AFL2.1</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>eb25444142d4102b0ce1b7ffaadb071e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/dbusglib-linux-20080707.tar.bz2</uri> - </map> - </map> - </map> - <key>elfio</key> - <map> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>82ea408af2f968cfe5f013ab241323ef</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/elfio-1.0.3-linux-20080812.tar.bz2</uri> - </map> - </map> - </map> - <key>expat</key> - <map> - <key>copyright</key> - <string>Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd</string> - <key>description</key> - <string>An XML parser library written in C. It is a stream-oriented parser in which an application registers handlers for things the parser might find in the XML document (like start tags).</string> - <key>license</key> - <string>mit</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>c457a0a041ac4946265889a503d26c3d</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/expat-1.95.8-darwin-20090805.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>67b470fd446b08c9831d1039674eae4e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/expat-1.95.8-linux-20080812.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>278c61871419b9a4d50a4f88b7922403</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/expat-1.95.8-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>5dbbdb4a9b5bec86d180ef20a5f8ccfb</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/expat-1.95.8-windows-20090917.tar.bz2</uri> - </map> - </map> - </map> - <key>fmod</key> - <map> - <key>copyright</key> - <string>FMOD Sound System, copyright (C) Firelight Technologies Pty, Ltd., 1994-2006.</string> - <key>description</key> - <string>Audio engine and mp3 stream decoder .</string> - <key>license</key> - <string>fmod</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>261bcd3387066cf0a1d46549400052b5</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/fmod-3.75-darwin-20101007.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>8490d97430c12c2e1ac19ff80a8d4db4</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/fmod-3.75-linux-20101007.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>bab1babcb01ff9849b7f072d352e1ecd</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/fmod-3.75-windows-20101007.tar.bz2</uri> - </map> - </map> - </map> - <key>fontconfig</key> - <map> - <key>license</key> - <string>mit</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>9af6a1ed39fa540bfcaa402b0ea22f78</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/fontconfig-2.2.3-linux-20080613.tar.bz2</uri> - </map> - </map> - </map> - <key>freeglut</key> - <map> - <key>license</key> - <string>mit</string> - <key>packages</key> - <map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>fcbb695ff203775fad96d184bf5f34fc</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freeglut-2.4.0-windows-20090608.tar.bz2</uri> - </map> - </map> - </map> - <key>freetype</key> - <map> - <key>copyright</key> - <string>Copyright</string> - <key>description</key> - <string>Font</string> - <key>license</key> - <string>freetype</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>f00144dfb597140f328774c3244f0c3e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freetype-2.3.9-darwin-20090922.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>9de3f44be65645c7f6af236139596942</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freetype-2.3.9-linux-2010-02-19a-nommap.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>35f6fa557ba90f9cda0a18d1af2055a4</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freetype-2.1.5-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>88980fd6d91ac541b62dea877ebe6ba6</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freetype-2.3.9-windows-20090917.tar.bz2</uri> - </map> - </map> - </map> - <key>glh_linear</key> - <map> - <key>copyright</key> - <string>Copyright (c) 2000 Cass Everitt; Copyright (c) 2000 NVIDIA Corporation; All rights reserved.</string> - <key>description</key> - <string>nVidia NVParse SDK: platform-indepenedent C++ Apple OpenGL helper library</string> - <key>license</key> - <string>glh_linear</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>23bd9a75e5a2365a827461e6c324f52b</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glh_linear-darwin-20080613.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>23bd9a75e5a2365a827461e6c324f52b</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glh_linear-linux-20080812.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>2965646aea1d2a6aec1fbc431c02733f</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glh_linear-linux-20080613.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>38b9ddfe8dceff55ee4351016a937d1b</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glh_linear-windows-20080613.tar.bz2</uri> - </map> - </map> - </map> - <key>glib</key> - <map> - <key>description</key> - <string>GLib is a library containing many useful C routines for things such as trees, hashes, and lists.</string> - <key>license</key> - <string>gpl</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>6cc5ce1fafd10299fdb890b3d4c3cf53</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glib-2.0-darwin-20080817.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>2f1a9e14f9213c2c9564c1c1cfdd6d47</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glib-2.0-linux-20080817.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>3d5e29d444dde4815b36082eedfc775a</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glib-2.0-windows-20080817.tar.bz2</uri> - </map> - </map> - </map> - <key>glui</key> - <map> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>84f792a860691d0fad6d1de6eeb31baa</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glui-2.36-darwin-20090623a.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>5b8631fe510d4ebaeb965c673937e1e7</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glui-2.3.6-windows-freeglut-20090608.tar.bz2</uri> - </map> - </map> - </map> - <key>google</key> - <map> - <key>license</key> - <string>mit</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>40db900872612615e849f17cbdfd2c27</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/google-linux-20080812.tar.bz2</uri> - </map> - </map> - </map> - <key>google-perftools</key> - <map> - <key>copyright</key> - <string>Copyright (c) 2005, Google Inc.</string> - <key>description</key> - <string>Heap performance and validity checking tools from google. Includes TCMalloc, heap-checker, heap-profiler and cpu-profiler.</string> - <key>license</key> - <string>bsd</string> - <key>packages</key> - <map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>32dba32ddd460a08e082898ebba6315c</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/google-perftools-1.0-windows-20090406.tar.bz2</uri> - </map> - </map> - </map> - <key>google_breakpad</key> - <map> - <key>copyright</key> - <string>Copyright (c) 2006, Google Inc.</string> - <key>description</key> - <string>An open-source multi-platform crash reporting system </string> - <key>license</key> - <string>bsd</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>ced4010b59f1a579caa7fe3c18512499</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/google_breakpad-0.0.0-rev599-darwin-20100528a.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>29c3e7dad60bbf02c811786436d99523</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/google_breakpad-0.0.0-rev599-linux-20100521b.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>0859d47242990125f17eaab30bece2ff</string> - <key>url</key> - <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/google_breakpad-0.0.0-rev599-windows-20100524.tar.bz2</uri> - </map> - </map> - </map> - <key>googlemock</key> - <map> - <key>copyright</key> - <string>Copyright 2008, Google Inc.</string> - <key>description</key> - <string>Google C++ Mocking Framework (or Google Mock for short) is a library for writing and using C++ mock classes.</string> - <key>license</key> - <string>bsd</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>4863e9fea433d0a4be761ea5d3e8346a</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-darwin-20090626.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>877dabecf84339690191c6115c76366e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-linux32-20090527.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>f601a82ea91030974072da8924cae41e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-windows-20090921.tar.bz2</uri> - </map> - </map> - </map> - <key>gstreamer</key> - <map> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>c829b638b6eef71ca63418cb9aea46a2</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/gstreamer-linux-20080613.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>befc7520fe01250f39458f65c29bc584</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/gstreamer-linux64-20080909.tar.bz2</uri> - </map> - </map> - </map> - <key>gtk-atk-pango-glib</key> - <map> - <key>copyright</key> - <string>Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald</string> - <key>description</key> - <string>Libraries associated with GTK for gui features. atk: interfaces for accessibility; glib: low-level core functionality for using GTK+ and GNOME; pango: layout/rendering of text w/ emphasis on internationalization.</string> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>21c16a74f8fc9a62e3ab944a6eb7403d</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/gtk-atk-pango-glib-linux-20080616.tar.bz</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>d963750bcd333a108b3697d220c87d09</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/gtk-atk-pango-glib-windows-20080613.tar.bz2</uri> - </map> - </map> - </map> - <key>havok</key> - <map> - <key>copyright</key> - <string>on file</string> - <key>description</key> - <string>Physics engine for the simulator</string> - <key>license</key> - <string>havok</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>f64c08771a4fc456db2a55b47302078b</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/havok-4.6-darwin-20080812.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>af7b1fc9072443009f19e43fb3c8342f</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/havok-4.6.1-linux-20081029.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>cd4076d6caf5fabff36bf48bd01e4ba8</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/havok-4.6.1-linux64-20081030.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>f25fbb29c2275267233c79f0c68ca37f</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/havok-4.6.1-windows-20081030.tar.bz2</uri> - </map> - </map> - </map> - <key>jpeglib</key> - <map> - <key>copyright</key> - <string>Copyright (c) 2003, Yves Piguet.</string> - <key>description</key> - <string>An open-source JPEG (JFIF) library</string> - <key>license</key> - <string>jpeglib</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>8d38d74c481e9aab4518c8f2a7d52800</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jpeglib-6b-darwin-20080812.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>8aa8e01e0c21f60f0ede0ffb04e9214f</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jpeglib-6b-linux-20081218.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>0e7facf7d48531d20c0cd6a3c3f04021</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jpeglib-6b-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>6a6bb0143a2561e3276dab4bcfa425ef</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jpeglib-6b-windows-20090917a.tar.bz2</uri> - </map> - </map> - </map> - <key>jsoncpp</key> - <map> - <key>copyright</key> - <string>json-cpp library released to Public Domain by Baptiste Lepilleur <blep@users.sourceforge.net></string> - <key>description</key> - <string>jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++.</string> - <key>license</key> - <string>jsoncpp</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>4c6b949778099a63550898f00f3e6a5e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-svn-r69-darwin-20090923.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>a2a94b8ca1d32f23e3e668d64023514e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-svn-r69-linux-20090922.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>a06ab38628ab7b53b8f3326cd942a6a8</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-svn-r69-linux64-20090922.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>caf152cfc730737c124f7612cf68fbd3</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-svn-r69-windows-20090922.tar.bz2</uri> - </map> - </map> - </map> - <key>kdu</key> - <map> - <key>copyright</key> - <string>on file</string> - <key>description</key> - <string>Kakadu (KDU) JPEG-2000 decoder library. </string> - <key>license</key> - <string>kdu</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>8261994de5af6581e08c26fefe1b2810</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/kdu-6.4.1-darwin-20101123.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>ed3e58899a424684dad49c94ba3813e7</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/kdu-6.4.1-linux-20101124.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>066e089a5d9faeaf131e1f4e4860a163</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/kdu-6.4.1-windows-20101123.tar.bz2</uri> - </map> - </map> - </map> - <key>libmono</key> - <map> - <key>copyright</key> - <string>(C) 2005 Novell, Inc. http://www.novell.com</string> - <key>description</key> - <string>An open source implementation of the ECMA/ISO ECMA-334 Common L\ -anguage Infrstructure (CLI) international standard</string> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>39a803fcbe6f11b72358fc78b7777b6c</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libmono-darwin-20080724.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>9bc0f8b7d5e0ff194b6d5635daf9ae3a</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libmono-1.2.6-linux-20080816a.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>451521b4cb57c35caf3efb8dcf99b99e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libmono-1.2.6-linux64-20080926.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>6712a09311a914752f47d5d62562a239</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libmono-1.2.6-windows-20080903.tar.bz2</uri> - </map> - </map> - </map> - <key>libpng</key> - <map> - <key>copyright</key> - <string>Copyright (c) 2004, 2006-2008 Glenn Randers-Pehrson</string> - <key>description</key> - <string>An open, extensible image format with lossless compression. PNG Reference Library </string> - <key>license</key> - <string>libpng</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>82659b48831cbf58bf04b86602939e0b</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libpng-1.2.35-darwin-20090304.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>f5e84c991f6e3caacb26db259593cbea</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libpng-1.2.35-linux-20090304.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>5ee1e62bde38520c7f134c4afb9ac9b1</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libpng-1.2.35-linux64-20090304.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>c781cd9846cf20afb90ac40ad1a0ce9d</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libpng-1.2.35-windows-20090917.tar.bz2</uri> - </map> - </map> - </map> - <key>libuuid</key> - <map> - <key>copyright</key> - <string>Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/></string> - <key>description</key> - <string>Generates UUIDs under Linux. Originally a part of the ext2fs filesystem. Also see lluuid.cpp for all platforms. Part of the e2fsprogs package.</string> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>91b194aed4b38bc23493b198009a8c6a</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libuuid-linux-20090417.tar.bz2</uri> - </map> - </map> - </map> - <key>libxml</key> - <map> - <key>license</key> - <string>mit</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>4b5d2dcfe8a49b73fb69f10aab441092</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libxml-2.6.24-linux-20080613.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>921d7f980519101afb74623e29e9d175</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libxml-2.6.24-linux64-20080909.tar.bz2</uri> - </map> - </map> - </map> - <key>llqtwebkit</key> - <map> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>f07b063cdc207479b111576dc74127f0</string> - <key>url</key> - <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-darwin-qt4.7.1-20110322.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>5d743c93b970abe685b185de83001a6e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-qt4.6-20100923.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>1e66b1ecab911a60ba50b59361ef62e1</string> - <key>url</key> - <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.7.1-20110317.tar.bz2</uri> - </map> - </map> - </map> - <key>mesa</key> - <map> - <key>copyright</key> - <string>Copyright (C) 1999-2007 Brian Paul All Rights Reserved.</string> - <key>description</key> - <string>Mesa 3-D graphics library. Provides the required Apple OpenGL headers under Linux.</string> - <key>license</key> - <string>mesa</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>70d0bbe1145fff29a0131349c898260e</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/mesa-7.0-linux-20080812.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>56630977f9261bd82039b0da08a0685c</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/mesa-6.2.1-linux64-20081016.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>82cdcdcb2d0615389a7480485ea35f4c</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/mesa-7.0-windows-20080613.tar.bz2</uri> - </map> - </map> - </map> - <key>mysql</key> - <map> - <key>license</key> - <string>gpl</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>df27f2db244ea2762759a06cd75ada4e</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/mysql-darwin-20080812.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>cc86b4cc858655e23704d1168325d7b9</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/mysqlclient-linux-20090320.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>98bac06680dca907e783d8dd4aa9edde</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/mysql-windows-20080804.tar.bz2</uri> - </map> - </map> - </map> - <key>ndofdev</key> - <map> - <key>copyright</key> - <string>Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved.</string> - <key>description</key> - <string>in use on windows and darwin for joystick support.</string> - <key>license</key> - <string>linden</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>17999c47e17f2dd9e12a22372ce8ff14</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-darwin-20080812.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>9469c3732a33a154fa0a2807b9f36ccc</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-0.2-20080828.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>f0df8a1e60991095e3adca1450b8c9c0</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-windows-20090917.tar.bz2</uri> - </map> - </map> - </map> - <key>ogg-vorbis</key> - <map> - <key>copyright</key> - <string>Copyright (C) 2008 Xiph.org Foundation</string> - <key>description</key> - <string>Ogg: container format Vorbis: audio compression scheme</string> - <key>license</key> - <string>ogg-vorbis</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>a6843398b780645c4897c9776c688926</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ogg-vorbis-1.03-1.1.2-darwin-20080812.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>6dc0536329a0aadf76e3054ffd4da61c</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ogg-vorbis-1.2.0-linux-20081201.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>964c71e6ee22be1bcaf6d480e74cdd14</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ogg-vorbis-1.2.0-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>9bf1fea65e66b2cd3075e6ffd7eb57ad</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ogg-vorbis-1.1.3-1.2.0-windows-20080723.tar.bz2</uri> - </map> - </map> - </map> - <key>openSSL</key> - <map> - <key>license</key> - <string>openSSL</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>11d2be4f2b172430747b7d4a6739e3d8</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openSSL-0.9.8l-darwin-20100428.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>f219ef07b02e2abb9282345c3a8f2b39</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openSSL-0.9.7c-linux-20080812.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>00b23f28a2457d9dabbaff0b29ee7323</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openSSL-0.9.8g-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>dd85209081b832e836de6e1538541d89</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openSSL-0.9.8j-windows-20090129.tar.bz2</uri> - </map> - </map> - </map> - <key>openal-soft</key> - <map> - <key>copyright</key> - <string>Copyright (C) 2008 by authors.</string> - <key>description</key> - <string>3D Audio library</string> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>a0757244e3e6688fde2ffeea35cc1f96</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-darwin-20080924.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>75a7004ab14bea46594b1c652f1a6040</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-linux-20100120-3ad86a1c.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>5ad0a3ab623356c1ad61394ba238f99f</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-soft-1.6.372-linux64-20081219.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>a0757244e3e6688fde2ffeea35cc1f96</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-windows-20080924.tar.bz2</uri> - </map> - </map> - </map> - <key>openjpeg</key> - <map> - <key>copyright</key> - <string>Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium</string> - <key>description</key> - <string>An open-source JPEG-2000 library; a slower alternative to Kadaku. Used in the open source release </string> - <key>license</key> - <string>openjpeg</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>23313fda213a2496945435db2a0ee78b</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openjpeg-1.3.0-darwin-20090501.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>02af0dad64803e0d821bc09e6038682c</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openjpeg-1.3-linux-20081124b.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>44f1bc9d47e4a54fc274c213f2cb565f</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openjpeg-1.2.0-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>41541a98106894e28a6bf585010fea65</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openjpeg-1.3-windows-20090407.tar.bz2</uri> - </map> - </map> - </map> - <key>pulseaudio</key> - <map> - <key>copyright</key> - <string>Copyright 2004-2006 Lennart Poettering, Copyright 2006 Pierre Ossman (ossman@cendio.se) for Cendio AB</string> - <key>description</key> - <string>pulseaudio: headers only</string> - <key>license</key> - <string>lgpl</string> - <key>packages</key> - <map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>30cb00069fe2a545fbf7be1070386236</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/linux-pulse-headers-0.9.14.tar.bz2</uri> - </map> - </map> - </map> - <key>quicktime</key> - <map> - <key>copyright</key> - <string>Copyright (C) 1990-2007 by Apple Computer, Inc., all rights reserved.</string> - <key>description</key> - <string>Separate download. Used to play in-world video clips on a prim. </string> - <key>license</key> - <string>quicktime</string> - <key>packages</key> - <map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>be45825cc14ede53790ac93c58307dcb</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/quicktime-sdk-windows-7.3-20091110.tar.bz2</uri> - </map> - </map> - </map> - <key>smartheap</key> - <map> - <key>copyright</key> - <string>Copyright (C) 1991-2000 Compuware Corporation. All Rights Reserved.</string> - <key>description</key> - <string>Memory Management Library</string> - <key>license</key> - <string>smartheap</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>f54131b5f228e805c64c2e4e6c96579a</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/smartheap-6.0.2-darwin-20080610.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>499208522bf7d7843e1d014d64214e06</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/smartheap-6.0.2-linux-20080610.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>78fd47017f21d11eae43bca3e38a3e1e</string> - <key>url</key> - <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/smartheap-6.0.2-windows-20080611.tar.bz2</uri> - </map> - </map> - </map> - <key>tut</key> - <map> - <key>copyright</key> - <string>Copyright 2002-2006 Vladimir Dyuzhev, Copyright 2007 Denis Kononenko, Copyright 2008 Michal Rzechonek</string> - <key>description</key> - <string>C++ Template Unit Test</string> - <key>license</key> - <string>bsd</string> - <key>packages</key> - <map> - <key>common</key> - <map> - <key>md5sum</key> - <string>a1b8a118ba9df1f2a73f6aafa7980e83</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/tut-2008-11-30-common-20081208.tar.bz2</uri> - </map> - </map> - </map> - <key>unistd</key> - <map> - <key>copyright</key> - <string>(c) 2008 Linden Lab.</string> - <key>description</key> - <string>Placeholder file to make flex happy on windows.</string> - <key>license</key> - <string>linden</string> - <key>packages</key> - <map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>6353aff33d7d03b22055aec76f53a866</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/unistd-windows-20080611.tar.bz2</uri> - </map> - </map> - </map> - <key>slvoice</key> - <map> - <key>copyright</key> - <string> </string> - <key>license</key> - <string>vivox</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>2f9b3528d4b5f858fb8dcee4b6dd5188</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-darwin-20101117a.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>cde4728b8a75a76c72a8785815cb769f</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-linux-20101117a.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>940ac55a6d0141c958bf2b14939d8474</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-windows-20101117a.tar.bz2</uri> - </map> - </map> - </map> - <key>xmlrpc-epi</key> - <map> - <key>copyright</key> - <string>Copyright 2000 Epinions, Inc.</string> - <key>description</key> - <string>Implementation of the xmlrpc protocol in C that provides an API for developers to serialize RPC requests to and from XML. </string> - <key>license</key> - <string>xmlrpc-epi</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>2d3a918c88d756422c1a8139ebe15f56</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/xmlrpc-epi-0.51-darwin-20080812.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>84a219199240ea70f54439c02acef0cd</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/xmlrpc-epi-0.51-linux-20080812.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>dc67b896c56116df8e18f2d1bbd07031</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/xmlrpc-epi-0.51-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>262629bcaa39dcf7266caa50da01a599</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/xmlrpc-epi-0.51-windows-20091016.tar.bz2</uri> - </map> - </map> - </map> - <key>zlib</key> - <map> - <key>copyright</key> - <string>Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler</string> - <key>description</key> - <string>A Massively Spiffy Yet Delicately Unobtrusive Compression Library (Also Free, Not to Mention Unencumbered by Patents)</string> - <key>license</key> - <string>zlib</string> - <key>packages</key> - <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>c844e1b05723ce078dbbd5aea9cdd3ad</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/zlib-1.1.4-darwin-20080818.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>26fe88213c213dc6153690ab142c25ca</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/zlib-1.2.3dfsg-linux-20091208.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>4bddfb2c6dd7b1470a3ed675ac14bd9a</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/zlib-1.2.3-linux64-20080909.tar.bz2</uri> - </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>73baf52a740d151fddbc2a008369c462</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/zlib-1.2.3-windows-20090921.tar.bz2</uri> - </map> - </map> - </map> - </map> - <key>licenses</key> - <map> - <key>AFL2.1</key> - <map> - <key>url</key> - <string>http://opensource-definition.org/licenses/afl-2.1.html</string> - </map> - <key>GL</key> - <map> - <key>url</key> - <string>http://www.xfree86.org/4.4.0/LICENSE9.html#sgi</string> - </map> - <key>MSDTW</key> - <map> - <key>text</key> - <string>MICROSOFT SOFTWARE LICENSE TERMS -MICROSOFT DEBUGGING TOOLS FOR WINDOWS -These license terms are an agreement between Microsoft Corporation (or based on where you live, one of -its affiliates) and you. Please read them. They apply to the software named above, which includes the -media on which you received it, if any. The terms also apply to any Microsoft -* updates, -* supplements, -* Internet-based services -* support services, and -* Debugging symbol files that you may access over the internet -for this software, unless other terms accompany those items. If so, those terms apply. -By using the software, you accept these terms. If you do not accept them, do not use the -software. -If you comply with these license terms, you have the rights below. -1. INSTALLATION AND USE RIGHTS. One user may install and use any number of copies of the -software on your devices to design, develop, debug and test your programs. -2. ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS. -a. Distributable Code. The software contains code that you are permitted to distribute in programs -you develop if you comply with the terms below. -i. Right to Use and Distribute. The code and text files listed below are Distributable Code. -* REDIST.TXT Files. You may copy and distribute the object code form of code listed in -REDIST.TXT files. -* Sample Code. You may modify, copy, and distribute the source and object code form of -code marked as sample. -* Third Party Distribution. You may permit distributors of your programs to copy and -distribute the Distributable Code as part of those programs. -ii. Distribution Requirements. For any Distributable Code you distribute, you must -* add significant primary functionality to it in your programs; -* require distributors and external end users to agree to terms that protect it at least as much -as this agreement; -* display your valid copyright notice on your programs; and -* indemnify, defend, and hold harmless Microsoft from any claims, including attorneys fees, -related to the distribution or use of your programs. -iii. Distribution Restrictions. You may not -* alter any copyright, trademark or patent notice in the Distributable Code; -* distribute any symbol files which you may access or use under these license terms for the -software; -* use Microsofts trademarks in your programs names or in a way that suggests your -programs come from or are endorsed by Microsoft; -* distribute Distributable Code to run on a platform other than the Windows platform; -* include Distributable Code in malicious, deceptive or unlawful programs; or -* modify or distribute the source code of any Distributable Code so that any part of it -becomes subject to an Excluded License. An Excluded License is one that requires, as a -condition of use, modification or distribution, that -* the code be disclosed or distributed in source code form; or -* others have the right to modify it. -3. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights -to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights -despite this limitation, you may use the software only as expressly permitted in this agreement. In -doing so, you must comply with any technical limitations in the software that only allow you to use it in -certain ways. You may not -* work around any technical limitations in the software; -* reverse engineer, decompile or disassemble the software, except and only to the extent that -applicable law expressly permits, despite this limitation; -* make more copies of the software than specified in this agreement or allowed by applicable law, -despite this limitation; -* publish the software for others to copy; -* rent, lease or lend the software; -* transfer the software or this agreement to any third party; or -* use the software for commercial software hosting services. -4. INTERNET-BASED SERVICES. Microsoft provides Internet-based services with the software. It may -change or cancel them at any time. -a. Consent for Internet-Based Services. The software contains features which may connect to -Microsoft or service provider computer systems over the Internet. In some cases, you will not -receive a separate notice when they connect. You may switch these features on or you may -choose not to use them. For more information about these features, see -http://www.microsoft.com/info/privacy/default.mspx. By using these features, you consent to the transmission of -this information. Microsoft does not use the information to identify or contact you. -b. Misuse of Internet-based Services. You may not use these services in any way that could -harm them or impair anyone elses use of them. You may not use the services to try to gain -unauthorized access to any service, data, account or network by any means. - -5. BACKUP COPY. You may make one backup copy of the software. You may use it only to reinstall the -software. -6. DOCUMENTATION. Any person that has valid access to your computer or internal network may copy -and use the documentation for your internal, reference purposes. -7. EXPORT RESTRICTIONS. The software is subject to United States export laws and regulations. You -must comply with all domestic and international export laws and regulations that apply to the software. -These laws include restrictions on destinations, end users and end use. For additional information, see -www.microsoft.com/exporting. -8. SUPPORT SERVICES. Because this software is as is, we may not provide support services for it. -9. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based -services and support services that you use, are the entire agreement for the software and support -services. -10. APPLICABLE LAW. -a. United States. If you acquired the software in the United States, Washington state law governs -the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of -laws principles. The laws of the state where you live govern all other claims, including claims under -state consumer protection laws, unfair competition laws, and in tort. -b. Outside the United States. If you acquired the software in any other country, the laws of that -country apply. -11. LEGAL EFFECT. This agreement describes certain legal rights. You may have other rights under the -laws of your country. You may also have rights with respect to the party from whom you acquired the -software. This agreement does not change your rights under the laws of your country if the laws of -your country do not permit it to do so. -12. DISCLAIMER OF WARRANTY. The software is licensed as-is. You bear the risk of using -it. Microsoft gives no express warranties, guarantees or conditions. You may have -additional consumer rights under your local laws which this agreement cannot change. To -the extent permitted under your local laws, Microsoft excludes the implied warranties of -merchantability, fitness for a particular purpose and non-infringement. -13. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. You can recover from -Microsoft and its suppliers only direct damages up to U.S. $5.00. You cannot recover any -other damages, including consequential, lost profits, special, indirect or incidental -damages. -This limitation applies to -* anything related to the software, services, content (including code) on third party Internet sites, or -third party programs; and -* claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, -or other tort to the extent permitted by applicable law. -It also applies even if Microsoft knew or should have known about the possibility of the damages. The -above limitation or exclusion may not apply to you because your country may not allow the exclusion or -limitation of incidental, consequential or other damages. - </string> - </map> - <key>apache 2.0</key> - <map> - <key>url</key> - <string>http://www.apache.org/licenses/LICENSE-2.0</string> - </map> - <key>artwork</key> - <map> - <key>text</key> - <string>COPYRIGHT AND PERMISSION NOTICE - -Second Life(TM) Viewer Artwork. Copyright (C) 2008 Linden Research, Inc. - -Linden Research, Inc. ("Linden Lab") licenses the Second Life viewer -artwork and other works in the files distributed with this Notice under -the Creative Commons Attribution-Share Alike 3.0 License, available at -http://creativecommons.org/licenses/by-sa/3.0/legalcode. For the license -summary, see http://creativecommons.org/licenses/by-sa/3.0/. - -Notwithstanding the foregoing, all of Linden Lab's trademarks, including -but not limited to the Second Life brand name and Second Life Eye-in-Hand -logo, are subject to our trademark policy at -http://secondlife.com/corporate/trademark/. - -If you distribute any copies or adaptations of the Second Life viewer -artwork or any other works in these files, you must include this Notice -and clearly identify any changes made to the original works. Include -this Notice and information where copyright notices are usually included, -for example, after your own copyright notice acknowledging your use of -the Second Life viewer artwork, in a text file distributed with your -program, in your application's About window, or on a credits page for -your work. -</string> - <key>url</key> - <string>http://svn.secondlife.com/svn/linden/trunk/doc/LICENSE-logos.txt</string> - </map> - <key>boost</key> - <map> - <key>url</key> - <string>http://www.boost.org/LICENSE_1_0.txt</string> - </map> - <key>bsd</key> - <map> - <key>url</key> - <string>http://www.opensource.org/licenses/bsd-license.php</string> - </map> - <key>c-ares</key> - <map> - <key>text</key> - <string>http://daniel.haxx.se/projects/c-ares/license.html</string> - </map> - <key>curl</key> - <map> - <key>url</key> - <string>http://curl.haxx.se/docs/copyright.html</string> - </map> - <key>fmod</key> - <map> - <key>url</key> - <string>http://www.fmod.org/ifmodlicense.html</string> - </map> - <key>freetype</key> - <map> - <key>url</key> - <string>http://freetype.sourceforge.net/FTL.TXT</string> - </map> - <key>glh_linear</key> - <map> - <key>text</key> - <string>glh - is a platform-indepenedent C++ OpenGL helper library - -Copyright (c) 2000 Cass Everitt -Copyright (c) 2000 NVIDIA Corporation -All rights reserved. - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following -conditions are met: - -Redistributions of source code must retain the above -copyright notice, this list of conditions and the following -disclaimer. -Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following -disclaimer in the documentation and/or other materials -provided with the distribution. -The names of contributors to this software may not be used -to endorse or promote products derived from this software -without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -Cass Everitt - cass@r3.nu - -</string> - </map> - <key>glut</key> - <map> - <key>url</key> - <string>http://www.xmission.com/~nate/glut/README-win32.txt</string> - </map> - <key>gpl</key> - <map> - <key>url</key> - <string>http://www.gnu.org/licenses/gpl.html</string> - </map> - <key>havok</key> - <map> - <key>text</key> - <string>on file</string> - </map> - <key>intel</key> - <map> - <key>text</key> - <string>Haven't yet found. -</string> - </map> - <key>jpeglib</key> - <map> - <key>text</key> - <string>http://nyctergatis.com/jpeglib/</string> - </map> - <key>jsoncpp</key> - <map> - <key>text</key> - <string>The json-cpp library and this documentation are in Public Domain. Retrieved from http://jsoncpp.sourceforge.net/ on 2009-09-04.</string> - <key>url</key> - <string>http://jsoncpp.sourceforge.net</string> - </map> - <key>kdu</key> - <map> - <key>text</key> - <string>jpeg2000 license #00024 (on file)</string> - </map> - <key>lgpl</key> - <map> - <key>url</key> - <string>http://www.gnu.org/copyleft/lgpl.html</string> - </map> - <key>libpng</key> - <map> - <key>text</key> - <string>http://www.libpng.org/pub/png/src/libpng-LICENSE.txt</string> - </map> - <key>linden</key> - <map> - <key>text</key> - <string>Using this license for Linden Lab owned library files</string> - </map> - <key>mesa</key> - <map> - <key>url</key> - <string>http://www.mesa3d.org/license.html</string> - </map> - <key>mit</key> - <map> - <key>text</key> - <string>http://www.jclark.com/xml/copying.txt</string> - </map> - <key>ogg-vorbis</key> - <map> - <key>url</key> - <string>http://www.xiph.org/licenses/bsd/</string> - </map> - <key>openSSL</key> - <map> - <key>url</key> - <string>http://www.openssl.org/source/license.html</string> - </map> - <key>openjpeg</key> - <map> - <key>url</key> - <string>http://www.openjpeg.org/BSDlicense.txt</string> - </map> - <key>quicktime</key> - <map> - <key>text</key> - <string>ENGLISH - -Apple Computer, Inc. -QuickTime 7 Software Developer Kit (SDK) -Software License Agreement - -PLEASE READ THIS SOFTWARE LICENSE AGREEMENT ("LICENSE") BEFORE USING THE SOFTWARE. BY USING THE SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS LICENSE. IF YOU ARE ACCESSING THE SOFTWARE ELECTRONICALLY, SIGNIFY YOUR AGREEMENT TO BE BOUND BY THE TERMS OF THIS LICENSE BY CLICKING THE "AGREE/ACCEPT" BUTTON. IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENSE, RETURN THE APPLE SOFTWARE TO THE PLACE WHERE YOU OBTAINED IT FOR A REFUND OR, IF THE SOFTWARE WAS ACCESSED ELECTRONICALLY, CLICK "DISAGREE/DECLINE". - -IMPORTANT NOTE: To the extent this software may be used to reproduce materials, it is licensed to you only for reproduction of materials you are authorized or legally permitted to reproduce. - -1. License. Any software, tools, utilities, sample code, documentation, fonts, API?s, header files and other materials accompanying this License, whether on disk, print or electronic documentation, in read only memory, or any other media, (collectively, the "Apple Software") are licensed, not sold, to you by Apple Computer, Inc. ("Apple") for use only under the terms of this License, and Apple reserves all rights not expressly granted to you. The rights granted herein are limited to Apple's and its licensors' intellectual property rights in the Apple Software and do not include any other patents or intellectual property rights. You own the media on which the Apple Software is recorded but Apple and/or Apple's licensor(s) retain ownership of the Apple Software itself. The Apple Software in this package and any copies, modifications and derivative works that this License authorizes you to make are subject to this License. - -2. Permitted Uses and Restrictions. You may use the Apple Software to develop application software that is compatible with, and runs only on Mac OS X and/or Windows platforms with QuickTime installed. Except for compiling header files and linking libraries as necessary to build your application software, you have no right to modify, incorporate into or include in combination with your own programs, license or otherwise redistribute any portion of the Apple Software. Your software application may not interfere with the functionality of QuickTime Player or the QuickTime Plug-in, including but not limited to file type or MIME type associations that are registered to QuickTime. You may make only as many internal use copies of the Apple Software as reasonably necessary to use the Apple Software as permitted in this paragraph and distribute such copies only to your employees whose job duties require them to so use the Apple Software. You must reproduce on each copy of the Apple Software or portion thereof, the Apple copyright notice and any other proprietary legends that were on the original copy of the Apple Software. Except as expressly permitted in this License, you may not decompile, reverse engineer, disassemble, modify, rent, lease, loan, sublicense, distribute or create derivative works based upon the Apple Software in whole or part. Your rights under this License will terminate automatically without notice from Apple if you fail to comply with any term(s) of this License. In addition, Apple reserves the right to terminate this License if a new version of Apple's operating system software or the Apple Software is released which is incompatible with the Apple Software. - -3. Disclaimer Of Warranty. The Apple Software may be "alpha", "beta", "development", pre-release, untested, and/or not fully tested and may contain errors that could cause failures or loss of data, be incomplete or contain inaccuracies. YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT USE OF THE APPLE SOFTWARE IS AT YOUR SOLE RISK AND THAT THE ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY AND EFFORT IS WITH YOU. EXCEPT FOR THE LIMITED WARRANTY ON MEDIA SET FORTH ABOVE AND TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE APPLE SOFTWARE IS PROVIDED "AS IS", WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND, AND APPLE AND APPLE'S LICENSORS (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE PURPOSES OF SECTIONS 4 AND 5) HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH RESPECT TO THE APPLE SOFTWARE, EITHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NON-INFRINGEMENT OF THIRD PARTY RIGHTS. APPLE DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE APPLE SOFTWARE, THAT THE FUNCTIONS CONTAINED IN THE APPLE SOFTWARE WILL MEET YOUR REQUIREMENTS, THAT THE OPERATION OF THE APPLE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE APPLE SOFTWARE WILL BE CORRECTED. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SHOULD THE APPLE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES OR LIMITATIONS ON APPLICABLE STATUTORY RIGHTS OF A CONSUMER, SO THE ABOVE EXCLUSION AND LIMITATIONS MAY NOT APPLY TO YOU. - -4. Limitation Of Liability. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT SHALL APPLE BE LIABLE FOR PERSONAL INJURY, OR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, LOSS OF DATA, BUSINESS INTERRUPTION OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO YOUR USE OR INABILITY TO USE THE APPLE SOFTWARE, HOWEVER CAUSED, REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, TORT OR OTHERWISE) AND EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY FOR PERSONAL INJURY, OR OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU. In no event shall Apple's total liability to you for all damages (other than as may be required by applicable law in cases involving personal injury) exceed the amount of fifty dollars ($50.00). The foregoing limitations will apply even if the above stated remedy fails of its essential purpose. - -5. Export Control. You may not use or otherwise export or reexport the Apple Product except as authorized by United States law and the laws of the jurisdiction in which the Apple Product was obtained. In particular, but without limitation, the Apple Product may not be exported or re-exported (a) into any U.S. embargoed countries or (b) to anyone on the U.S. Treasury Department's list of Specially Designated Nationals or the U.S. Department of Commerce Denied Person?s List or Entity List. By using the Apple Product, you represent and warrant that you are not located in any such country or on any such list. - -6. Government End Users. The Apple Software and related documentation are "Commercial Items", as that term is defined at 48 C.F.R. ?2.101, consisting of "Commercial Computer Software" and "Commercial Computer Software Documentation", as such terms are used in 48 C.F.R. ?12.212 or 48 C.F.R. ?227.7202, as applicable. Consistent with 48 C.F.R. ?12.212 or 48 C.F.R. ?227.7202-1through 227.7202-4, as applicable, the Commercial Computer Software and Commercial Computer Software Documentation are being licensed to U.S. Government end users (a) only as Commercial Items and (b) with only those rights as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States. - -7. Controlling Law and Severability. This License will be governed by and construed in accordance with the laws of the State of California, as applied to agreements entered into and to be performed entirely within California between California residents. This License shall not be governed by the United Nations Convention on Contracts for the International Sale of Goods, the application of which is expressly excluded. If for any reason a court of competent jurisdiction finds any provision, or portion thereof, to be unenforceable, the remainder of this License shall continue in full force and effect. - -8. Complete Agreement. This License constitutes the entire agreement between the parties with respect to the use of the Apple Software licensed hereunder and supersedes all prior or contemporaneous understandings regarding such subject matter. No amendment to or modification of this License will be binding unless in writing and signed by Apple. Any translation of this License is done for local requirements and in the event of a dispute between the English and any non-English versions, the English version of this License shall govern. - -EA0300 -</string> - </map> - <key>sleepycat</key> - <map> - <key>url</key> - <string>http://opensource.org/licenses/sleepycat.php</string> - </map> - <key>smartheap</key> - <map> - <key>text</key> - <string>on file -</string> - </map> - <key>things</key> - <map> - </map> - <key>vivox</key> - <map> - <key>text</key> - <string>on file</string> - </map> - <key>xmlrpc-epi</key> - <map> - <key>url</key> - <string>http://xmlrpc-epi.sourceforge.net/main.php?t=license</string> - </map> - <key>zlib</key> - <map> - <key>url</key> - <string>http://www.gzip.org/zlib/zlib_license.html</string> - </map> - </map> - </map> -</llsd> diff --git a/scripts/md5check.py b/scripts/md5check.py index 1a54a2844c..1a54a2844c 100644..100755 --- a/scripts/md5check.py +++ b/scripts/md5check.py |