diff options
author | Monty Brandenberg <monty@lindenlab.com> | 2013-09-19 13:13:37 -0400 |
---|---|---|
committer | Monty Brandenberg <monty@lindenlab.com> | 2013-09-19 13:13:37 -0400 |
commit | eaef5e63d5f5e3177fbd13de41aea12340f2fa30 (patch) | |
tree | 4da9c9af2741b2d33eb05cebe0291e50aada88ba /indra/newview | |
parent | 195d319f65239238577ae15c22188da3839ae5cf (diff) | |
parent | ad777b46d0fe5d790e43efb1771e9f64f3ad3dfb (diff) |
Merge. Pull in viewer-release after materials viewer release.
Diffstat (limited to 'indra/newview')
87 files changed, 4950 insertions, 1984 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e2ae7a5a9a..3a09bc530c 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1272,6 +1272,11 @@ set_source_files_properties( if (DARWIN) LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp) + LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm) + LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h) + + # This should be compiled with the viewer. + LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm) find_library(AGL_LIBRARY AGL) find_library(APPKIT_LIBRARY AppKit) @@ -1292,7 +1297,7 @@ if (DARWIN) macview.r gpu_table.txt Info-SecondLife.plist - SecondLife.nib/ + SecondLife.xib/ # CMake doesn't seem to support Xcode language variants well just yet English.lproj/InfoPlist.strings English.lproj/language.txt @@ -1972,20 +1977,25 @@ if (LINUX) endif (LINUX) if (DARWIN) + # These all get set with PROPERTIES set(product "Second Life") - + set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer") + set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") + set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}") + set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007") + set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib") + set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication") + set_target_properties( ${VIEWER_BINARY_NAME} PROPERTIES OUTPUT_NAME "${product}" - MACOSX_BUNDLE_INFO_STRING "Second Life Viewer" - MACOSX_BUNDLE_ICON_FILE "secondlife.icns" - MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer" - MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" - MACOSX_BUNDLE_BUNDLE_NAME "Second Life" - MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}" - MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}" - MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007" + MACOSX_BUNDLE_INFO_PLIST + "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist" ) configure_file( diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index a19844f11c..9b8136a827 100755 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -5,19 +5,33 @@ <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> - <string>Second Life</string> + <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> + <key>CFBundleGetInfoString</key> + <string>${MACOSX_BUNDLE_INFO_STRING}</string> <key>CFBundleIconFile</key> - <string>secondlife.icns</string> + <string>${MACOSX_BUNDLE_ICON_FILE}</string> <key>CFBundleIdentifier</key> - <string>com.secondlife.indra.viewer</string> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> + <key>CFBundleLongVersionString</key> + <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> <key>CFBundleName</key> - <string>Second Life</string> + <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> <key>CFBundlePackageType</key> <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> <key>CFBundleSignature</key> <string>????</string> + <key>CFBundleVersion</key> + <string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string> + <key>CSResourcesFileMapped</key> + <true/> + <key>LSRequiresCarbon</key> + <true/> + <key>NSHumanReadableCopyright</key> + <string>${MACOSX_BUNDLE_COPYRIGHT}</string> <key>CFBundleDocumentTypes</key> <array> <dict> @@ -59,9 +73,9 @@ <true/> </dict> </array> - <key>CFBundleVersion</key> - <string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string> - <key>CSResourcesFileMapped</key> - <true/> + <key>NSPrincipalClass</key> + <string>${MACOSX_BUNDLE_NSPRINCIPAL_CLASS}</string> + <key>NSMainNibFile</key> + <string>${MACOSX_BUNDLE_NSMAIN_NIB_FILE}</string> </dict> </plist> diff --git a/indra/newview/SecondLife.nib b/indra/newview/SecondLife.nib Binary files differnew file mode 100644 index 0000000000..8b99b5a770 --- /dev/null +++ b/indra/newview/SecondLife.nib diff --git a/indra/newview/SecondLife.nib/classes.nib b/indra/newview/SecondLife.nib/classes.nib deleted file mode 100755 index ea58db1189..0000000000 --- a/indra/newview/SecondLife.nib/classes.nib +++ /dev/null @@ -1,4 +0,0 @@ -{ -IBClasses = (); -IBVersion = 1; -} diff --git a/indra/newview/SecondLife.nib/info.nib b/indra/newview/SecondLife.nib/info.nib deleted file mode 100755 index 1b531de104..0000000000 --- a/indra/newview/SecondLife.nib/info.nib +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>IBDocumentLocation</key> - <string>85 13 356 240 0 0 1280 1002 </string> - <key>IBEditorPositions</key> - <dict> - <key>29</key> - <string>27 314 247 44 0 0 1280 1002 </string> - </dict> - <key>IBFramework Version</key> - <string>362.0</string> - <key>IBOpenObjects</key> - <array> - <integer>191</integer> - </array> - <key>IBSystem Version</key> - <string>7D24</string> - <key>targetFramework</key> - <string>IBCarbonFramework</string> -</dict> -</plist> diff --git a/indra/newview/SecondLife.nib/objects.xib b/indra/newview/SecondLife.nib/objects.xib deleted file mode 100755 index b7ff30f2b2..0000000000 --- a/indra/newview/SecondLife.nib/objects.xib +++ /dev/null @@ -1,259 +0,0 @@ -<?xml version="1.0" standalone="yes"?> -<object class="NSIBObjectData"> - <string name="targetFramework">IBCarbonFramework</string> - <object name="rootObject" class="NSCustomObject" id="1"> - <string name="customClass">NSApplication</string> - </object> - <array count="31" name="allObjects"> - <object class="IBCarbonMenu" id="29"> - <string name="title">SecondLife</string> - <array count="4" name="items"> - <object class="IBCarbonMenuItem" id="182"> - <string name="title">Second Life</string> - <object name="submenu" class="IBCarbonMenu" id="181"> - <string name="title">Second Life</string> - <array count="1" name="items"> - <object class="IBCarbonMenuItem" id="183"> - <boolean name="disabled">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">About Second Life</string> - <int name="keyEquivalentModifier">0</int> - <ostype name="command">abou</ostype> - </object> - </array> - <string name="name">_NSAppleMenu</string> - </object> - </object> - <object class="IBCarbonMenuItem" id="127"> - <string name="title">File</string> - <object name="submenu" class="IBCarbonMenu" id="131"> - <string name="title">File</string> - </object> - </object> - <object class="IBCarbonMenuItem" id="152"> - <string name="title">Edit</string> - <object name="submenu" class="IBCarbonMenu" id="147"> - <string name="title">Edit</string> - <array count="10" name="items"> - <object class="IBCarbonMenuItem" id="141"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Undo</string> - <string name="keyEquivalent">z</string> - <ostype name="command">undo</ostype> - </object> - <object class="IBCarbonMenuItem" id="146"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Redo</string> - <string name="keyEquivalent">Z</string> - <ostype name="command">redo</ostype> - </object> - <object class="IBCarbonMenuItem" id="142"> - <boolean name="separator">TRUE</boolean> - </object> - <object class="IBCarbonMenuItem" id="143"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Cut</string> - <string name="keyEquivalent">x</string> - <ostype name="command">cut </ostype> - </object> - <object class="IBCarbonMenuItem" id="149"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Copy</string> - <string name="keyEquivalent">c</string> - <ostype name="command">copy</ostype> - </object> - <object class="IBCarbonMenuItem" id="144"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Paste</string> - <string name="keyEquivalent">v</string> - <ostype name="command">past</ostype> - </object> - <object class="IBCarbonMenuItem" id="151"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Delete</string> - <ostype name="command">clea</ostype> - </object> - <object class="IBCarbonMenuItem" id="148"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Select All</string> - <string name="keyEquivalent">a</string> - <ostype name="command">sall</ostype> - </object> - <object class="IBCarbonMenuItem" id="188"> - <boolean name="separator">TRUE</boolean> - </object> - <object class="IBCarbonMenuItem" id="187"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Special Characters…</string> - <ostype name="command">chrp</ostype> - </object> - </array> - </object> - </object> - <object class="IBCarbonMenuItem" id="153"> - <string name="title">Window</string> - <object name="submenu" class="IBCarbonMenu" id="154"> - <string name="title">Window</string> - <array count="6" name="items"> - <object class="IBCarbonMenuItem" id="155"> - <boolean name="dynamic">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Minimize Window</string> - <string name="keyEquivalent">m</string> - <ostype name="command">mini</ostype> - </object> - <object class="IBCarbonMenuItem" id="184"> - <boolean name="dynamic">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Minimize All Windows</string> - <string name="keyEquivalent">m</string> - <int name="keyEquivalentModifier">1572864</int> - <ostype name="command">mina</ostype> - </object> - <object class="IBCarbonMenuItem" id="186"> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Zoom</string> - <ostype name="command">zoom</ostype> - </object> - <object class="IBCarbonMenuItem" id="156"> - <boolean name="separator">TRUE</boolean> - </object> - <object class="IBCarbonMenuItem" id="157"> - <boolean name="dynamic">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Bring All to Front</string> - <ostype name="command">bfrt</ostype> - </object> - <object class="IBCarbonMenuItem" id="185"> - <boolean name="dynamic">TRUE</boolean> - <boolean name="updateSingleItem">TRUE</boolean> - <string name="title">Arrange in Front</string> - <int name="keyEquivalentModifier">1572864</int> - <ostype name="command">frnt</ostype> - </object> - </array> - <string name="name">_NSWindowsMenu</string> - </object> - </object> - </array> - <string name="name">_NSMainMenu</string> - </object> - <reference idRef="127"/> - <reference idRef="131"/> - <reference idRef="141"/> - <reference idRef="142"/> - <reference idRef="143"/> - <reference idRef="144"/> - <reference idRef="146"/> - <reference idRef="147"/> - <reference idRef="148"/> - <reference idRef="149"/> - <reference idRef="151"/> - <reference idRef="152"/> - <reference idRef="153"/> - <reference idRef="154"/> - <reference idRef="155"/> - <reference idRef="156"/> - <reference idRef="157"/> - <reference idRef="181"/> - <reference idRef="182"/> - <reference idRef="183"/> - <reference idRef="184"/> - <reference idRef="185"/> - <reference idRef="186"/> - <reference idRef="187"/> - <reference idRef="188"/> - <object class="IBCarbonRootControl" id="190"> - <string name="bounds">0 0 482 694 </string> - <string name="viewFrame">0 0 694 482 </string> - <array count="2" name="subviews"> - <object class="IBCarbonButton" id="192"> - <string name="bounds">442 604 462 674 </string> - <string name="viewFrame">604 442 70 20 </string> - <string name="title">OK</string> - <ostype name="command">ok </ostype> - <object name="layoutInfo" class="IBCarbonHILayoutInfo"> - <int name="bindingBottomKind">2</int> - <int name="bindingRightKind">2</int> - </object> - <int name="buttonType">1</int> - </object> - <object class="IBCarbonScrollView" id="201"> - <string name="bounds">20 20 422 674 </string> - <string name="viewFrame">20 20 654 402 </string> - <array count="1" name="subviews"> - <object class="IBCarbonTextView" id="200"> - <string name="bounds">20 20 422 659 </string> - <string name="viewFrame">0 0 639 402 </string> - <ostype name="controlSignature">text</ostype> - <int name="fontStyle">5</int> - <boolean name="readOnly">TRUE</boolean> - </object> - </array> - <boolean name="scrollHorizontally">FALSE</boolean> - </object> - </array> - </object> - <object class="IBCarbonWindow" id="191"> - <string name="windowRect">84 72 566 766 </string> - <string name="title">Release Notes</string> - <reference name="rootControl" idRef="190"/> - <boolean name="receiveUpdates">FALSE</boolean> - <boolean name="hasCloseBox">FALSE</boolean> - <boolean name="hasCollapseBox">FALSE</boolean> - <boolean name="hasHorizontalZoom">FALSE</boolean> - <boolean name="isResizable">FALSE</boolean> - <boolean name="hasVerticalZoom">FALSE</boolean> - <boolean name="liveResize">TRUE</boolean> - <boolean name="compositing">TRUE</boolean> - <int name="carbonWindowClass">4</int> - <int name="windowPosition">1</int> - <boolean name="isConstrained">FALSE</boolean> - </object> - <reference idRef="192"/> - <reference idRef="200"/> - <reference idRef="201"/> - </array> - <array count="31" name="allParents"> - <reference idRef="1"/> - <reference idRef="29"/> - <reference idRef="127"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="152"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="29"/> - <reference idRef="29"/> - <reference idRef="153"/> - <reference idRef="154"/> - <reference idRef="154"/> - <reference idRef="154"/> - <reference idRef="182"/> - <reference idRef="29"/> - <reference idRef="181"/> - <reference idRef="154"/> - <reference idRef="154"/> - <reference idRef="154"/> - <reference idRef="147"/> - <reference idRef="147"/> - <reference idRef="191"/> - <reference idRef="1"/> - <reference idRef="190"/> - <reference idRef="201"/> - <reference idRef="190"/> - </array> - <dictionary count="3" name="nameTable"> - <string>Files Owner</string> - <reference idRef="1"/> - <string>MenuBar</string> - <reference idRef="29"/> - <string>Release Notes</string> - <reference idRef="191"/> - </dictionary> - <unsigned_int name="nextObjectID">202</unsigned_int> -</object> diff --git a/indra/newview/SecondLife.xib b/indra/newview/SecondLife.xib new file mode 100644 index 0000000000..370df6bf5f --- /dev/null +++ b/indra/newview/SecondLife.xib @@ -0,0 +1,1136 @@ +<?xml version="1.0" encoding="UTF-8"?> +<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00"> + <data> + <int key="IBDocument.SystemTarget">1060</int> + <string key="IBDocument.SystemVersion">12E55</string> + <string key="IBDocument.InterfaceBuilderVersion">4457.6</string> + <string key="IBDocument.AppKitVersion">1187.39</string> + <string key="IBDocument.HIToolboxVersion">626.00</string> + <object class="NSMutableDictionary" key="IBDocument.PluginVersions"> + <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="NS.object.0">4457.6</string> + </object> + <array key="IBDocument.IntegratedClassDependencies"> + <string>NSCustomObject</string> + <string>NSMenu</string> + <string>NSMenuItem</string> + <string>NSScrollView</string> + <string>NSScroller</string> + <string>NSTextView</string> + <string>NSView</string> + <string>NSWindowTemplate</string> + </array> + <array key="IBDocument.PluginDependencies"> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + </array> + <object class="NSMutableDictionary" key="IBDocument.Metadata"> + <string key="NS.key.0">PluginDependencyRecalculationVersion</string> + <integer value="1" key="NS.object.0"/> + </object> + <array class="NSMutableArray" key="IBDocument.RootObjects" id="1048"> + <object class="NSCustomObject" id="1021"> + <string key="NSClassName">NSApplication</string> + </object> + <object class="NSCustomObject" id="1014"> + <string key="NSClassName">FirstResponder</string> + </object> + <object class="NSCustomObject" id="1050"> + <string key="NSClassName">NSApplication</string> + </object> + <object class="NSMenu" id="649796088"> + <string key="NSTitle">Main Menu</string> + <array class="NSMutableArray" key="NSMenuItems"> + <object class="NSMenuItem" id="694149608"> + <reference key="NSMenu" ref="649796088"/> + <string key="NSTitle">Second Life</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <object class="NSCustomResource" key="NSOnImage" id="353210768"> + <string key="NSClassName">NSImage</string> + <string key="NSResourceName">NSMenuCheckmark</string> + </object> + <object class="NSCustomResource" key="NSMixedImage" id="549394948"> + <string key="NSClassName">NSImage</string> + <string key="NSResourceName">NSMenuMixedState</string> + </object> + <string key="NSAction">submenuAction:</string> + <object class="NSMenu" key="NSSubmenu" id="110575045"> + <string key="NSTitle">Second Life</string> + <array class="NSMutableArray" key="NSMenuItems"> + <object class="NSMenuItem" id="238522557"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">About Second Life</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="304266470"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="609285721"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Preferences…</string> + <string key="NSKeyEquiv">,</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="481834944"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="1046388886"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Services</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + <string key="NSAction">submenuAction:</string> + <object class="NSMenu" key="NSSubmenu" id="752062318"> + <string key="NSTitle">Services</string> + <array class="NSMutableArray" key="NSMenuItems"/> + <string key="NSName">_NSServicesMenu</string> + </object> + </object> + <object class="NSMenuItem" id="646227648"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="755159360"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Hide NewApplication</string> + <string key="NSKeyEquiv">h</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="342932134"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Hide Others</string> + <string key="NSKeyEquiv">h</string> + <int key="NSKeyEquivModMask">1572864</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="908899353"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Show All</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="1056857174"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="632727374"> + <reference key="NSMenu" ref="110575045"/> + <string key="NSTitle">Quit Second Life</string> + <string key="NSKeyEquiv">q</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + </array> + <string key="NSName">_NSAppleMenu</string> + </object> + </object> + <object class="NSMenuItem" id="725688984"> + <reference key="NSMenu" ref="649796088"/> + <string key="NSTitle">Edit</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + <string key="NSAction">submenuAction:</string> + <object class="NSMenu" key="NSSubmenu" id="701759256"> + <string key="NSTitle">Edit</string> + <array class="NSMutableArray" key="NSMenuItems"> + <object class="NSMenuItem" id="521487141"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Undo</string> + <string key="NSKeyEquiv">z</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="668936019"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Redo</string> + <string key="NSKeyEquiv">Z</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="383018193"> + <reference key="NSMenu" ref="701759256"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="984623395"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Cut</string> + <string key="NSKeyEquiv">x</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="656529582"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Copy</string> + <string key="NSKeyEquiv">c</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="1032676691"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Paste</string> + <string key="NSKeyEquiv">v</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="538907583"> + <reference key="NSMenu" ref="701759256"/> + <string key="NSTitle">Select All</string> + <string key="NSKeyEquiv">a</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + </array> + </object> + </object> + <object class="NSMenuItem" id="713487014"> + <reference key="NSMenu" ref="649796088"/> + <string key="NSTitle">Window</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + <string key="NSAction">submenuAction:</string> + <object class="NSMenu" key="NSSubmenu" id="835318025"> + <string key="NSTitle">Window</string> + <array class="NSMutableArray" key="NSMenuItems"> + <object class="NSMenuItem" id="1011231497"> + <reference key="NSMenu" ref="835318025"/> + <string key="NSTitle">Minimize</string> + <string key="NSKeyEquiv">m</string> + <int key="NSKeyEquivModMask">1048576</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="575023229"> + <reference key="NSMenu" ref="835318025"/> + <string key="NSTitle">Zoom</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="86356408"> + <reference key="NSMenu" ref="835318025"/> + <string key="NSTitle">Enter Full Screen</string> + <string key="NSKeyEquiv">f</string> + <int key="NSKeyEquivModMask">1310720</int> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="299356726"> + <reference key="NSMenu" ref="835318025"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + <object class="NSMenuItem" id="625202149"> + <reference key="NSMenu" ref="835318025"/> + <string key="NSTitle">Bring All to Front</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + </array> + <string key="NSName">_NSWindowsMenu</string> + </object> + </object> + <object class="NSMenuItem" id="391199113"> + <reference key="NSMenu" ref="649796088"/> + <string key="NSTitle">Help</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> + </array> + <string key="NSName">_NSMainMenu</string> + </object> + <object class="NSCustomObject" id="756173070"> + <string key="NSClassName">LLAppDelegate</string> + </object> + <object class="NSWindowTemplate" id="110292814"> + <int key="NSWindowStyleMask">15</int> + <int key="NSWindowBacking">2</int> + <string key="NSWindowRect">{{196, 240}, {1024, 600}}</string> + <int key="NSWTFlags">74974208</int> + <string key="NSWindowTitle">Second Life</string> + <string key="NSWindowClass">LLNSWindow</string> + <nil key="NSViewClass"/> + <nil key="NSUserInterfaceItemIdentifier"/> + <object class="NSView" key="NSWindowView" id="305280978"> + <reference key="NSNextResponder"/> + <int key="NSvFlags">256</int> + <array class="NSMutableArray" key="NSSubviews"/> + <string key="NSFrameSize">{1024, 600}</string> + <reference key="NSSuperview"/> + <reference key="NSWindow"/> + <string key="NSReuseIdentifierKey">_NS:20</string> + </object> + <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string> + <string key="NSMaxSize">{10000000000000, 10000000000000}</string> + <string key="NSFrameAutosaveName">Second Life</string> + <int key="NSWindowCollectionBehavior">128</int> + <bool key="NSWindowIsRestorable">YES</bool> + </object> + <object class="NSWindowTemplate" id="979091056"> + <int key="NSWindowStyleMask">31</int> + <int key="NSWindowBacking">2</int> + <string key="NSWindowRect">{{272, 176}, {938, 42}}</string> + <int key="NSWTFlags">-1535638528</int> + <string key="NSWindowTitle">Input Window</string> + <string key="NSWindowClass">LLUserInputWindow</string> + <nil key="NSViewClass"/> + <nil key="NSUserInterfaceItemIdentifier"/> + <object class="NSView" key="NSWindowView" id="1044753903"> + <reference key="NSNextResponder"/> + <int key="NSvFlags">256</int> + <array class="NSMutableArray" key="NSSubviews"> + <object class="NSScrollView" id="238626476"> + <reference key="NSNextResponder" ref="1044753903"/> + <int key="NSvFlags">256</int> + <array class="NSMutableArray" key="NSSubviews"> + <object class="NSClipView" id="871543330"> + <reference key="NSNextResponder" ref="238626476"/> + <int key="NSvFlags">2322</int> + <array class="NSMutableArray" key="NSSubviews"> + <object class="NSTextView" id="395788163"> + <reference key="NSNextResponder" ref="871543330"/> + <int key="NSvFlags">2322</int> + <set class="NSMutableSet" key="NSDragTypes"> + <string>Apple HTML pasteboard type</string> + <string>Apple PDF pasteboard type</string> + <string>Apple PICT pasteboard type</string> + <string>Apple PNG pasteboard type</string> + <string>Apple URL pasteboard type</string> + <string>CorePasteboardFlavorType 0x6D6F6F76</string> + <string>NSColor pasteboard type</string> + <string>NSFilenamesPboardType</string> + <string>NSStringPboardType</string> + <string>NeXT Encapsulated PostScript v1.2 pasteboard type</string> + <string>NeXT RTFD pasteboard type</string> + <string>NeXT Rich Text Format v1.0 pasteboard type</string> + <string>NeXT TIFF v4.0 pasteboard type</string> + <string>NeXT font pasteboard type</string> + <string>NeXT ruler pasteboard type</string> + <string>WebURLsWithTitlesPboardType</string> + <string>public.url</string> + </set> + <string key="NSFrameSize">{938, 42}</string> + <reference key="NSSuperview" ref="871543330"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="339833963"/> + <string key="NSReuseIdentifierKey">_NS:13</string> + <object class="NSTextContainer" key="NSTextContainer" id="648552009"> + <object class="NSLayoutManager" key="NSLayoutManager"> + <object class="NSTextStorage" key="NSTextStorage"> + <object class="NSMutableString" key="NSString"> + <characters key="NS.bytes"/> + </object> + <nil key="NSDelegate"/> + </object> + <array class="NSMutableArray" key="NSTextContainers"> + <reference ref="648552009"/> + </array> + <int key="NSLMFlags">166</int> + <nil key="NSDelegate"/> + </object> + <reference key="NSTextView" ref="395788163"/> + <double key="NSWidth">938</double> + <int key="NSTCFlags">1</int> + </object> + <object class="NSTextViewSharedData" key="NSSharedData"> + <int key="NSFlags">67121127</int> + <int key="NSTextCheckingTypes">0</int> + <nil key="NSMarkedAttributes"/> + <object class="NSColor" key="NSBackgroundColor" id="535647664"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MQA</bytes> + </object> + <dictionary key="NSSelectedAttributes"> + <object class="NSColor" key="NSBackgroundColor"> + <int key="NSColorSpace">6</int> + <string key="NSCatalogName">System</string> + <string key="NSColorName">selectedTextBackgroundColor</string> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes> + </object> + </object> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">6</int> + <string key="NSCatalogName">System</string> + <string key="NSColorName">selectedTextColor</string> + <object class="NSColor" key="NSColor" id="835883401"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MAA</bytes> + </object> + </object> + </dictionary> + <reference key="NSInsertionColor" ref="835883401"/> + <dictionary key="NSLinkAttributes"> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">1</int> + <bytes key="NSRGB">MCAwIDEAA</bytes> + </object> + <object class="NSCursor" key="NSCursor"> + <string key="NSHotSpot">{8, -8}</string> + <int key="NSCursorType">13</int> + </object> + <integer value="1" key="NSUnderline"/> + </dictionary> + <nil key="NSDefaultParagraphStyle"/> + <nil key="NSTextFinder"/> + <int key="NSPreferredTextFinderStyle">1</int> + </object> + <int key="NSTVFlags">6</int> + <string key="NSMaxSize">{939, 10000000}</string> + <nil key="NSDelegate"/> + </object> + </array> + <string key="NSFrame">{{1, 1}, {938, 42}}</string> + <reference key="NSSuperview" ref="238626476"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="395788163"/> + <string key="NSReuseIdentifierKey">_NS:11</string> + <reference key="NSDocView" ref="395788163"/> + <reference key="NSBGColor" ref="535647664"/> + <object class="NSCursor" key="NSCursor"> + <string key="NSHotSpot">{4, 5}</string> + <object class="NSImage" key="NSImage"> + <int key="NSImageFlags">79691776</int> + <array key="NSReps"> + <array> + <integer value="5"/> + <object class="NSURL"> + <nil key="NS.base"/> + <string key="NS.relative">file://localhost/Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework/Resources/DVTIbeamCursor.tiff</string> + </object> + </array> + </array> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MCAwAA</bytes> + </object> + </object> + </object> + <int key="NScvFlags">4</int> + </object> + <object class="NSScroller" id="339833963"> + <reference key="NSNextResponder" ref="238626476"/> + <int key="NSvFlags">256</int> + <string key="NSFrame">{{923, 1}, {16, 42}}</string> + <reference key="NSSuperview" ref="238626476"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView"/> + <string key="NSReuseIdentifierKey">_NS:83</string> + <bool key="NSAllowsLogicalLayoutDirection">NO</bool> + <reference key="NSTarget" ref="238626476"/> + <string key="NSAction">_doScroller:</string> + <double key="NSPercent">0.96666666666666667</double> + </object> + <object class="NSScroller" id="1067057765"> + <reference key="NSNextResponder" ref="238626476"/> + <int key="NSvFlags">-2147483392</int> + <string key="NSFrame">{{-100, -100}, {87, 18}}</string> + <reference key="NSSuperview" ref="238626476"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="871543330"/> + <string key="NSReuseIdentifierKey">_NS:33</string> + <bool key="NSAllowsLogicalLayoutDirection">NO</bool> + <int key="NSsFlags">1</int> + <reference key="NSTarget" ref="238626476"/> + <string key="NSAction">_doScroller:</string> + <double key="NSCurValue">1</double> + <double key="NSPercent">0.94565218687057495</double> + </object> + </array> + <string key="NSFrame">{{-1, -1}, {940, 44}}</string> + <reference key="NSSuperview" ref="1044753903"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="1067057765"/> + <string key="NSReuseIdentifierKey">_NS:9</string> + <int key="NSsFlags">133138</int> + <reference key="NSVScroller" ref="339833963"/> + <reference key="NSHScroller" ref="1067057765"/> + <reference key="NSContentView" ref="871543330"/> + <double key="NSMinMagnification">0.25</double> + <double key="NSMaxMagnification">4</double> + <double key="NSMagnification">1</double> + </object> + </array> + <string key="NSFrameSize">{938, 42}</string> + <reference key="NSSuperview"/> + <reference key="NSWindow"/> + <reference key="NSNextKeyView" ref="238626476"/> + <string key="NSReuseIdentifierKey">_NS:21</string> + </object> + <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string> + <string key="NSMaxSize">{10000000000000, 10000000000000}</string> + <bool key="NSWindowIsRestorable">YES</bool> + </object> + </array> + <object class="IBObjectContainer" key="IBDocument.Objects"> + <array class="NSMutableArray" key="connectionRecords"> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">terminate:</string> + <reference key="source" ref="1050"/> + <reference key="destination" ref="632727374"/> + </object> + <int key="connectionID">823</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">orderFrontStandardAboutPanel:</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="238522557"/> + </object> + <int key="connectionID">142</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">delegate</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="756173070"/> + </object> + <int key="connectionID">845</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">performMiniaturize:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="1011231497"/> + </object> + <int key="connectionID">37</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">arrangeInFront:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="625202149"/> + </object> + <int key="connectionID">39</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">performZoom:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="575023229"/> + </object> + <int key="connectionID">240</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">hide:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="755159360"/> + </object> + <int key="connectionID">369</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">hideOtherApplications:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="342932134"/> + </object> + <int key="connectionID">370</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">unhideAllApplications:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="908899353"/> + </object> + <int key="connectionID">372</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">cut:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="984623395"/> + </object> + <int key="connectionID">768</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">paste:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="1032676691"/> + </object> + <int key="connectionID">769</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">undo:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="521487141"/> + </object> + <int key="connectionID">776</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">copy:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="656529582"/> + </object> + <int key="connectionID">782</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">selectAll:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="538907583"/> + </object> + <int key="connectionID">785</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">toggleFullScreen:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="86356408"/> + </object> + <int key="connectionID">842</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">window</string> + <reference key="source" ref="756173070"/> + <reference key="destination" ref="110292814"/> + </object> + <int key="connectionID">850</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">inputWindow</string> + <reference key="source" ref="756173070"/> + <reference key="destination" ref="979091056"/> + </object> + <int key="connectionID">953</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">inputView</string> + <reference key="source" ref="756173070"/> + <reference key="destination" ref="395788163"/> + </object> + <int key="connectionID">954</int> + </object> + </array> + <object class="IBMutableOrderedSet" key="objectRecords"> + <array key="orderedObjects"> + <object class="IBObjectRecord"> + <int key="objectID">0</int> + <array key="object" id="0"/> + <reference key="children" ref="1048"/> + <nil key="parent"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-2</int> + <reference key="object" ref="1021"/> + <reference key="parent" ref="0"/> + <string key="objectName">File's Owner</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-1</int> + <reference key="object" ref="1014"/> + <reference key="parent" ref="0"/> + <string key="objectName">First Responder</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-3</int> + <reference key="object" ref="1050"/> + <reference key="parent" ref="0"/> + <string key="objectName">Application</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">29</int> + <reference key="object" ref="649796088"/> + <array class="NSMutableArray" key="children"> + <reference ref="713487014"/> + <reference ref="694149608"/> + <reference ref="391199113"/> + <reference ref="725688984"/> + </array> + <reference key="parent" ref="0"/> + <string key="objectName">Main Menu</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">19</int> + <reference key="object" ref="713487014"/> + <array class="NSMutableArray" key="children"> + <reference ref="835318025"/> + </array> + <reference key="parent" ref="649796088"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">56</int> + <reference key="object" ref="694149608"/> + <array class="NSMutableArray" key="children"> + <reference ref="110575045"/> + </array> + <reference key="parent" ref="649796088"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">103</int> + <reference key="object" ref="391199113"/> + <array class="NSMutableArray" key="children"/> + <reference key="parent" ref="649796088"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">57</int> + <reference key="object" ref="110575045"/> + <array class="NSMutableArray" key="children"> + <reference ref="238522557"/> + <reference ref="755159360"/> + <reference ref="908899353"/> + <reference ref="632727374"/> + <reference ref="646227648"/> + <reference ref="609285721"/> + <reference ref="481834944"/> + <reference ref="304266470"/> + <reference ref="1046388886"/> + <reference ref="1056857174"/> + <reference ref="342932134"/> + </array> + <reference key="parent" ref="694149608"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">58</int> + <reference key="object" ref="238522557"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">134</int> + <reference key="object" ref="755159360"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">150</int> + <reference key="object" ref="908899353"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">136</int> + <reference key="object" ref="632727374"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">144</int> + <reference key="object" ref="646227648"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">129</int> + <reference key="object" ref="609285721"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">143</int> + <reference key="object" ref="481834944"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">236</int> + <reference key="object" ref="304266470"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">131</int> + <reference key="object" ref="1046388886"/> + <array class="NSMutableArray" key="children"> + <reference ref="752062318"/> + </array> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">149</int> + <reference key="object" ref="1056857174"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">145</int> + <reference key="object" ref="342932134"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">130</int> + <reference key="object" ref="752062318"/> + <reference key="parent" ref="1046388886"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">24</int> + <reference key="object" ref="835318025"/> + <array class="NSMutableArray" key="children"> + <reference ref="299356726"/> + <reference ref="625202149"/> + <reference ref="575023229"/> + <reference ref="1011231497"/> + <reference ref="86356408"/> + </array> + <reference key="parent" ref="713487014"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">92</int> + <reference key="object" ref="299356726"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">5</int> + <reference key="object" ref="625202149"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">239</int> + <reference key="object" ref="575023229"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">23</int> + <reference key="object" ref="1011231497"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">711</int> + <reference key="object" ref="725688984"/> + <array class="NSMutableArray" key="children"> + <reference ref="701759256"/> + </array> + <reference key="parent" ref="649796088"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">712</int> + <reference key="object" ref="701759256"/> + <array class="NSMutableArray" key="children"> + <reference ref="521487141"/> + <reference ref="668936019"/> + <reference ref="383018193"/> + <reference ref="984623395"/> + <reference ref="656529582"/> + <reference ref="1032676691"/> + <reference ref="538907583"/> + </array> + <reference key="parent" ref="725688984"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">716</int> + <reference key="object" ref="984623395"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">717</int> + <reference key="object" ref="656529582"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">718</int> + <reference key="object" ref="1032676691"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">721</int> + <reference key="object" ref="538907583"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">824</int> + <reference key="object" ref="756173070"/> + <reference key="parent" ref="0"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">841</int> + <reference key="object" ref="86356408"/> + <reference key="parent" ref="835318025"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">828</int> + <reference key="object" ref="110292814"/> + <array class="NSMutableArray" key="children"> + <reference ref="305280978"/> + </array> + <reference key="parent" ref="0"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">829</int> + <reference key="object" ref="305280978"/> + <array class="NSMutableArray" key="children"/> + <reference key="parent" ref="110292814"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">713</int> + <reference key="object" ref="521487141"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">714</int> + <reference key="object" ref="668936019"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">715</int> + <reference key="object" ref="383018193"/> + <reference key="parent" ref="701759256"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">941</int> + <reference key="object" ref="979091056"/> + <array class="NSMutableArray" key="children"> + <reference ref="1044753903"/> + </array> + <reference key="parent" ref="0"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">942</int> + <reference key="object" ref="1044753903"/> + <array class="NSMutableArray" key="children"> + <reference ref="238626476"/> + </array> + <reference key="parent" ref="979091056"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">943</int> + <reference key="object" ref="238626476"/> + <array class="NSMutableArray" key="children"> + <reference ref="395788163"/> + <reference ref="1067057765"/> + <reference ref="339833963"/> + </array> + <reference key="parent" ref="1044753903"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">944</int> + <reference key="object" ref="395788163"/> + <reference key="parent" ref="238626476"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">945</int> + <reference key="object" ref="1067057765"/> + <reference key="parent" ref="238626476"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">946</int> + <reference key="object" ref="339833963"/> + <reference key="parent" ref="238626476"/> + </object> + </array> + </object> + <dictionary class="NSMutableDictionary" key="flattenedProperties"> + <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="103.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="711.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="712.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="713.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="714.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="715.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="716.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="717.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="718.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="721.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="824.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <boolean value="YES" key="828.IBNSWindowAutoPositionCentersHorizontal"/> + <boolean value="YES" key="828.IBNSWindowAutoPositionCentersVertical"/> + <string key="828.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <boolean value="YES" key="828.NSWindowTemplate.visibleAtLaunch"/> + <string key="829.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="841.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="941.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <boolean value="NO" key="941.NSWindowTemplate.visibleAtLaunch"/> + <string key="942.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="943.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="944.CustomClassName">LLNonInlineTextView</string> + <string key="944.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="945.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + <string key="946.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> + </dictionary> + <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/> + <nil key="activeLocalization"/> + <dictionary class="NSMutableDictionary" key="localizations"/> + <nil key="sourceID"/> + <int key="maxID">954</int> + </object> + <object class="IBClassDescriber" key="IBDocument.Classes"> + <array class="NSMutableArray" key="referencedPartialClassDescriptions"> + <object class="IBPartialClassDescription"> + <string key="className">LLAppDelegate</string> + <string key="superclassName">NSObject</string> + <dictionary class="NSMutableDictionary" key="outlets"> + <string key="inputView">LLNonInlineTextView</string> + <string key="inputWindow">NSWindow</string> + <string key="window">LLNSWindow</string> + </dictionary> + <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName"> + <object class="IBToOneOutletInfo" key="inputView"> + <string key="name">inputView</string> + <string key="candidateClassName">LLNonInlineTextView</string> + </object> + <object class="IBToOneOutletInfo" key="inputWindow"> + <string key="name">inputWindow</string> + <string key="candidateClassName">NSWindow</string> + </object> + <object class="IBToOneOutletInfo" key="window"> + <string key="name">window</string> + <string key="candidateClassName">LLNSWindow</string> + </object> + </dictionary> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/LLAppDelegate.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">LLNSWindow</string> + <string key="superclassName">NSWindow</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/LLNSWindow.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">LLNonInlineTextView</string> + <string key="superclassName">NSTextView</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/LLNonInlineTextView.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">LLUserInputWindow</string> + <string key="superclassName">NSPanel</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/LLUserInputWindow.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">NSTextView</string> + <dictionary class="NSMutableDictionary" key="actions"> + <string key="orderFrontSharingServicePicker:">id</string> + <string key="toggleQuickLookPreviewPanel:">id</string> + </dictionary> + <dictionary class="NSMutableDictionary" key="actionInfosByName"> + <object class="IBActionInfo" key="orderFrontSharingServicePicker:"> + <string key="name">orderFrontSharingServicePicker:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="toggleQuickLookPreviewPanel:"> + <string key="name">toggleQuickLookPreviewPanel:</string> + <string key="candidateClassName">id</string> + </object> + </dictionary> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/NSTextView.h</string> + </object> + </object> + </array> + </object> + <int key="IBDocument.localizationMode">0</int> + <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string> + <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies"> + <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string> + <real value="1060" key="NS.object.0"/> + </object> + <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies"> + <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string> + <integer value="4600" key="NS.object.0"/> + </object> + <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool> + <int key="IBDocument.defaultPropertyAccessControl">3</int> + <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes"> + <string key="NSMenuCheckmark">{11, 11}</string> + <string key="NSMenuMixedState">{10, 3}</string> + </dictionary> + </data> +</archive> diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index d15b8b06fa..5b3413147c 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.6.5 +3.6.7 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 60fc2d349d..a9f1fb1249 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3579,13 +3579,13 @@ </map> <key>FilterItemsMaxTimePerFrameUnvisible</key> <map> - <key>Comment</key> + <key>Comment</key> <string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> <integer>1</integer> </map> <key>FindLandArea</key> @@ -8831,6 +8831,18 @@ </array> </map> + <key>RenderSpecularPrecision</key> + <map> + <key>Comment</key> + <string>Force 32-bit floating point LUT</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>0</real> + </map> + <key>RenderSpecularResX</key> <map> <key>Comment</key> @@ -9121,6 +9133,17 @@ <key>Value</key> <real>1.0</real> </map> + <key>RenderDeferredDisplayGamma</key> + <map> + <key>Comment</key> + <string>Gamma ramp exponent for final correction before display gamma.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>2.2</real> + </map> <key>RenderGLCoreProfile</key> <map> <key>Comment</key> @@ -9848,6 +9871,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>RenderWaterMaterials</key> + <map> + <key>Comment</key> + <string>Water planar reflections include materials rendering.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderWaterMipNormal</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 0899caa2af..cd7a76db28 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -35,6 +35,26 @@ out vec4 frag_color; #define frag_color gl_FragColor #endif +uniform float display_gamma; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform float haze_horizon; +uniform float haze_density; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float distance_multiplier; +uniform float max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform mat3 env_mat; +uniform mat3 ssao_effect_mat; + +uniform vec3 sun_dir; + #if HAS_SHADOW uniform sampler2DShadow shadowMap0; uniform sampler2DShadow shadowMap1; @@ -53,14 +73,8 @@ uniform float shadow_bias; uniform sampler2D diffuseMap; #endif -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; VARYING vec2 vary_texcoord0; VARYING vec3 vary_norm; @@ -68,12 +82,73 @@ VARYING vec3 vary_norm; VARYING vec4 vertex_color; #endif +vec3 vary_PositionEye; +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + uniform vec4 light_position[8]; uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; -uniform vec2 screen_res; +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); +#endif + +} + +vec2 encode_normal(vec3 n) +{ + float f = sqrt(8 * n.z + 8); + return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ + vec2 fenc = enc*4-2; + float f = dot(fenc,fenc); + float g = sqrt(1-f/4); + vec3 n; + n.xy = fenc*g; + n.z = 1-f/2; + return n; +} vec3 calcDirectionalLight(vec3 n, vec3 l) { @@ -82,7 +157,7 @@ vec3 calcDirectionalLight(vec3 n, vec3 l) return vec3(a,a,a); } -vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) { //get light vector vec3 lv = lp.xyz-v; @@ -90,7 +165,9 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float //get distance float d = length(lv); - float da = 0.0; + float da = 1.0; + + vec3 col = vec3(0); if (d > 0.0 && la > 0.0 && fa > 0.0) { @@ -99,20 +176,25 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float //distance attenuation float dist = d/la; - da = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); - da *= da; - da *= 1.4; - + float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); + dist_atten *= dist_atten; + dist_atten *= 2.0; // spotlight coefficient. float spot = max(dot(-ln, lv), is_pointlight); da *= spot*spot; // GL_SPOT_EXPONENT=2 //angular attenuation - da *= max(dot(n, lv), 0.0); + da *= max(dot(n, lv), 0.0); + + float lit = max(da * dist_atten,0.0); + + col = light_col * lit * diffuse; + + // no spec for alpha shader... } - return vec3(da,da,da); + return max(col, vec3(0.0,0.0,0.0)); } #if HAS_SHADOW @@ -135,6 +217,237 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc) } #endif +#ifdef WATER_FOG +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec4 applyWaterFogDeferred(vec3 pos, vec4 color) +{ + //normalize view vector + vec3 view = normalize(pos); + float es = -(dot(view, waterPlane.xyz)); + + //find intersection point with water plane and eye vector + + //get eye depth + float e0 = max(-waterPlane.w, 0.0); + + vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); + + //get object depth + float depth = length(pos - int_v); + + //get "thickness" of water + float l = max(depth, 0.1); + + float kd = waterFogDensity; + float ks = waterFogKS; + vec4 kc = waterFogColor; + + float F = 0.98; + + float t1 = -kd * pow(F, ks * e0); + float t2 = kd + ks * es; + float t3 = pow(F, t2*l) - 1.0; + + float L = min(t1/t2*t3, 1.0); + + float D = pow(0.98, l*kd); + + color.rgb = color.rgb * D + kc.rgb * L; + color.a = kc.a + color.a; + + return color; +} +#endif + +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); + + 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 + vec4(haze_density * 0.25)) * (density_multiplier * max_y); + //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); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density) / 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; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier); + + //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 * 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) + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * 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 / vec3(scene_light_strength, scene_light_strength, scene_light_strength)); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength)); +} + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f)); +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity); +} + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + vec3 zeroes = vec3(0.0f, 0.0f, 0.0f); + vec3 ones = vec3(1.0f, 1.0f, 1.0f); + + light = ones - clamp(light, zeroes, ones); + light = ones - pow(light, gamma.xxx); + + return light; +} + +vec3 fullbrightAtmosTransport(vec3 light) { + float brightness = dot(light.rgb, vec3(0.33333)); + + return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); +} + +vec3 fullbrightScaleSoftClip(vec3 light) +{ + //soft clip effect: + return light; +} void main() { @@ -143,13 +456,15 @@ void main() vec4 pos = vec4(vary_position, 1.0); + float shadow = 1.0; -#if HAS_SHADOW - float shadow = 0.0; +#if HAS_SHADOW vec4 spos = pos; if (spos.z > -shadow_clip.w) { + shadow = 0.0; + vec4 lpos; vec4 near_split = shadow_clip*-0.75; @@ -215,40 +530,77 @@ void main() #else vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); #endif - vec4 gamma_diff = diff; - diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f)); +#ifdef FOR_IMPOSTOR + vec4 color; + color.rgb = diff.rgb; #ifdef USE_VERTEX_COLOR - float vertex_color_alpha = vertex_color.a; + float final_alpha = diff.a * vertex_color.a; + diff.rgb *= vertex_color.rgb; #else - float vertex_color_alpha = 1.0; + float final_alpha = diff.a; #endif - - vec3 normal = vary_norm; - - vec3 l = light_position[0].xyz; - vec3 dlight = calcDirectionalLight(normal, l); - dlight = dlight * vary_directional.rgb * vary_pointlight_col; -#if HAS_SHADOW - vec4 col = vec4(vary_ambient + dlight * shadow, vertex_color_alpha); + // Insure we don't pollute depth with invis pixels in impostor rendering + // + if (final_alpha < 0.01) + { + discard; + } +#else + +#ifdef USE_VERTEX_COLOR + float final_alpha = diff.a * vertex_color.a; + diff.rgb *= vertex_color.rgb; #else - vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha); + float final_alpha = diff.a; #endif - vec4 color = gamma_diff * col; - - color.rgb = atmosLighting(color.rgb); + vec4 gamma_diff = diff; + diff.rgb = srgb_to_linear(diff.rgb); + + vec3 norm = vary_norm; + + calcAtmospherics(pos.xyz, 1.0); + + vec2 abnormal = encode_normal(norm.xyz); + norm.xyz = decode_normal(abnormal.xy); + + float da = dot(norm.xyz, sun_dir.xyz); + + float final_da = da; + final_da = min(final_da, shadow); + final_da = max(final_da, 0.0f); + final_da = min(final_da, 1.0f); + final_da = pow(final_da, 1.0/1.3); + + vec4 color = vec4(0,0,0,0); + + color.rgb = atmosAmbient(color.rgb); + color.a = final_alpha; + + float ambient = abs(da); + ambient *= 0.5; + ambient *= ambient; + ambient = (1.0-ambient); + + color.rgb *= ambient; + color.rgb += atmosAffectDirectionalLight(final_da); + color.rgb *= gamma_diff.rgb; + + //color.rgb = mix(diff.rgb, color.rgb, final_alpha); + + color.rgb = atmosLighting(color.rgb); color.rgb = scaleSoftClip(color.rgb); - color.rgb = pow(color.rgb, vec3(2.2)); - col = vec4(0,0,0,0); + vec4 light = vec4(0,0,0,0); - - #define LIGHT_LOOP(i) col.rgb += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + color.rgb = srgb_to_linear(color.rgb); + #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + LIGHT_LOOP(1) LIGHT_LOOP(2) LIGHT_LOOP(3) @@ -257,9 +609,19 @@ void main() LIGHT_LOOP(6) LIGHT_LOOP(7) - color.rgb += diff.rgb * pow(vary_pointlight_col, vec3(2.2)) * col.rgb; + // keep it linear + // + color.rgb += light.rgb; - color.rgb = pow(color.rgb, vec3(1.0/2.2)); + // straight to display gamma, we're post-deferred + // + color.rgb = linear_to_srgb(color.rgb); + +#ifdef WATER_FOG + color = applyWaterFogDeferred(pos.xyz, color); +#endif + +#endif frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 9d3ba564cd..60d414f2ff 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -55,67 +55,18 @@ mat4 getSkinnedTransform(); #endif #endif -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -void calcAtmospherics(vec3 inPositionEye); - -vec3 atmosAmbient(vec3 light); -vec3 atmosAffectDirectionalLight(float lightIntensity); -vec3 scaleDownLight(vec3 light); -vec3 scaleUpLight(vec3 light); - -VARYING vec3 vary_ambient; -VARYING vec3 vary_directional; VARYING vec3 vary_fragcoord; VARYING vec3 vary_position; -VARYING vec3 vary_pointlight_col; #ifdef USE_VERTEX_COLOR VARYING vec4 vertex_color; #endif VARYING vec2 vary_texcoord0; - VARYING vec3 vary_norm; uniform float near_clip; -uniform vec4 light_position[8]; -uniform vec3 light_direction[8]; -uniform vec3 light_attenuation[8]; -uniform vec3 light_diffuse[8]; - -uniform vec3 sun_dir; - -vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) -{ - //get light vector - vec3 lv = lp.xyz-v; - - //get distance - float d = dot(lv,lv); - - float da = 0.0; - - if (d > 0.0 && la > 0.0 && fa > 0.0) - { - //normalize light vector - lv = normalize(lv); - - //distance attenuation - float dist2 = d/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 - - //angular attenuation - da *= max(dot(n, lv), 0.0); - } - - return vec3(da,da,da); -} - void main() { vec4 pos; @@ -168,43 +119,10 @@ void main() vary_norm = norm; vary_position = pos.xyz; - calcAtmospherics(pos.xyz); - -#ifndef USE_VERTEX_COLOR - vec4 diffuse_color = vec4(1,1,1,1); -#endif - //vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.)); - vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); - - vec3 diff = diffuse_color.rgb; - - - - vary_pointlight_col = diff; - - - col.rgb = vec3(0,0,0); - - // Add windlight lights - col.rgb = atmosAmbient(col.rgb); - - float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); - ambient *= 0.5; - ambient *= ambient; - ambient = (1.0-ambient); - - col.rgb *= ambient; - - vary_ambient = col.rgb*diff.rgb; - - vary_directional.rgb = atmosAffectDirectionalLight(1.0f); - - col.rgb = col.rgb*diff.rgb; - #ifdef USE_VERTEX_COLOR - vertex_color = col; + vertex_color = diffuse_color; #endif - + #ifdef HAS_SKIN vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); #else @@ -219,4 +137,3 @@ void main() #endif } - diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 968a5f6b3d..a4f54dff70 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -59,22 +59,6 @@ vec4 getPosition(vec2 pos_screen) return pos; } -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -91,7 +75,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index 59d109b886..8525e13333 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -50,7 +50,7 @@ void main() { discard; } - + frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index dc1dead656..f22b16965c 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -35,29 +35,143 @@ out vec4 frag_color; uniform sampler2D diffuseMap; #endif +VARYING vec3 vary_position; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -vec3 fullbrightAtmosTransport(vec3 light); -vec3 fullbrightScaleSoftClip(vec3 light); +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); +#endif + +} + +vec3 fullbrightAtmosTransportDeferred(vec3 light) +{ + return light; +} + +vec3 fullbrightScaleSoftClipDeferred(vec3 light) +{ + //soft clip effect: + return light; +} + +#ifdef HAS_ALPHA_MASK +uniform float minimum_alpha; +#endif + +#ifdef WATER_FOG +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec4 applyWaterFogDeferred(vec3 pos, vec4 color) +{ + //normalize view vector + vec3 view = normalize(pos); + float es = -(dot(view, waterPlane.xyz)); + + //find intersection point with water plane and eye vector + + //get eye depth + float e0 = max(-waterPlane.w, 0.0); + + vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); + + //get object depth + float depth = length(pos - int_v); + + //get "thickness" of water + float l = max(depth, 0.1); + + float kd = waterFogDensity; + float ks = waterFogKS; + vec4 kc = waterFogColor; + + float F = 0.98; + + float t1 = -kd * pow(F, ks * e0); + float t2 = kd + ks * es; + float t3 = pow(F, t2*l) - 1.0; + + float L = min(t1/t2*t3, 1.0); + + float D = pow(0.98, l*kd); + + color.rgb = color.rgb * D + kc.rgb * L; + color.a = kc.a + color.a; + + return color; +} +#endif void main() { #if HAS_DIFFUSE_LOOKUP - vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color; + vec4 color = diffuseLookup(vary_texcoord0.xy); #else - vec4 color = texture2D(diffuseMap, vary_texcoord0.xy)*vertex_color; + vec4 color = texture2D(diffuseMap, vary_texcoord0.xy); #endif - color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f)); - - color.rgb = fullbrightAtmosTransport(color.rgb); + float final_alpha = color.a * vertex_color.a; - color.rgb = fullbrightScaleSoftClip(color.rgb); +#ifdef HAS_ALPHA_MASK + if (color.a < minimum_alpha) + { + discard; + } +#endif + + color.rgb *= vertex_color.rgb; + color.rgb = srgb_to_linear(color.rgb); + color.rgb = fullbrightAtmosTransportDeferred(color.rgb); + color.rgb = fullbrightScaleSoftClipDeferred(color.rgb); + + color.rgb = linear_to_srgb(color.rgb); - color.rgb = pow(color.rgb, vec3(1.0/2.2)); +#ifdef WATER_FOG + vec3 pos = vary_position; + vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha)); + color.rgb = fogged.rgb; + color.a = fogged.a; +#else + color.a = final_alpha; +#endif - frag_color = color; + frag_color.rgb = color.rgb; + frag_color.a = color.a; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 3f09a15375..8e899e3e0f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -40,6 +40,9 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 scaleDownLight(vec3 light); vec3 scaleUpLight(vec3 light); +#ifdef WATER_FOG +VARYING vec3 vary_position; +#endif VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; @@ -53,7 +56,11 @@ void main() passTextureIndex(); gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); - + +#ifdef WATER_FOG + vary_position = pos.xyz; +#endif + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl index 2cef8f2a5d..a2b4b3b8c8 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index bc0719cb82..f8fdde43f9 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -38,6 +38,42 @@ uniform sampler2D specularMap; VARYING vec2 vary_texcoord0; +vec3 decode_normal (vec2 enc) +{ + vec2 fenc = enc*4-2; + float f = dot(fenc,fenc); + float g = sqrt(1-f/4); + vec3 n; + n.xy = fenc*g; + n.z = 1-f/2; + return n; +} + +vec2 encode_normal(vec3 n) +{ + float f = sqrt(8 * n.z + 8); + return n.xy / f + 0.5; +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); +#endif + +} + void main() { vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -47,7 +83,12 @@ void main() discard; } - frag_data[0] = vec4(col.rgb, col.a * 0.005); - frag_data[1] = texture2D(specularMap, vary_texcoord0.xy); - frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0); + vec4 norm = texture2D(normalMap, vary_texcoord0.xy); + vec4 spec = texture2D(specularMap, vary_texcoord0.xy); + + col.rgb = linear_to_srgb(col.rgb); + + frag_data[0] = vec4(col.rgb, 0.0); + frag_data[1] = spec; + frag_data[2] = vec4(norm.xy,0,0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 618ea747f5..8202b4978f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -29,6 +29,44 @@ #define DIFFUSE_ALPHA_MODE_EMISSIVE 3 uniform float emissive_brightness; +uniform float display_gamma; + +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); +#endif + +} #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) @@ -114,6 +152,52 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; +#ifdef WATER_FOG +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec4 applyWaterFogDeferred(vec3 pos, vec4 color) +{ + //normalize view vector + vec3 view = normalize(pos); + float es = -(dot(view, waterPlane.xyz)); + + //find intersection point with water plane and eye vector + + //get eye depth + float e0 = max(-waterPlane.w, 0.0); + + vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); + + //get object depth + float depth = length(pos - int_v); + + //get "thickness" of water + float l = max(depth, 0.1); + + float kd = waterFogDensity; + float ks = waterFogKS; + vec4 kc = waterFogColor; + + float F = 0.98; + + float t1 = -kd * pow(F, ks * e0); + float t2 = kd + ks * es; + float t3 = pow(F, t2*l) - 1.0; + + float L = min(t1/t2*t3, 1.0); + + float D = pow(0.98, l*kd); + + color.rgb = color.rgb * D + kc.rgb * L; + color.a = kc.a + color.a; + + return color; +} +#endif + vec3 calcDirectionalLight(vec3 n, vec3 l) { float a = max(dot(n,l),0.0); @@ -142,7 +226,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe float dist = d/la; float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); dist_atten *= dist_atten; - dist_atten *= 1.4; + dist_atten *= 2.0; // spotlight coefficient. float spot = max(dot(-ln, lv), is_pointlight); @@ -199,10 +283,13 @@ vec4 getPosition_d(vec2 pos_screen, float depth) return pos; } +#ifndef WATER_FOG vec3 getPositionEye() { return vary_PositionEye; } +#endif + vec3 getSunlitColor() { return vary_SunlitColor; @@ -428,22 +515,6 @@ VARYING vec3 vary_normal; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -460,7 +531,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif void main() { @@ -475,8 +545,8 @@ void main() #endif #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - vec3 old_diffcol = diffcol.rgb; - diffcol.rgb = pow(diffcol.rgb, vec3(2.2)); + vec3 gamma_diff = diffcol.rgb; + diffcol.rgb = srgb_to_linear(diffcol.rgb); #endif #if HAS_SPECULAR_MAP @@ -502,6 +572,9 @@ void main() norm.xyz = tnorm; norm.xyz = normalize(norm.xyz); + vec2 abnormal = encode_normal(norm.xyz); + norm.xyz = decode_normal(abnormal.xy); + vec4 final_color = diffcol; #if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) @@ -597,7 +670,7 @@ void main() vec4 diffuse = final_color; float envIntensity = final_normal.z; - vec3 col = vec3(0.0f,0.0f,0.0f); + vec3 col = vec3(0.0f,0.0f,0.0f); float bloom = 0.0; calcAtmospherics(pos.xyz, 1.0); @@ -605,23 +678,27 @@ void main() vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); float da =dot(norm.xyz, sun_dir.xyz); + float final_da = da; final_da = min(final_da, shadow); - final_da = max(final_da, diffuse.a); + //final_da = max(final_da, diffuse.a); final_da = max(final_da, 0.0f); + final_da = min(final_da, 1.0f); + final_da = pow(final_da, 1.0/1.3); col.rgb = atmosAmbient(col); - float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); + float ambient = min(abs(da), 1.0); ambient *= 0.5; ambient *= ambient; ambient = (1.0-ambient); col.rgb *= ambient; - col.rgb = col.rgb + atmosAffectDirectionalLight(pow(final_da, 1.0/1.3)); - col.rgb *= old_diffcol.rgb; - + col.rgb = col.rgb + atmosAffectDirectionalLight(final_da); + + col.rgb *= gamma_diff.rgb; + float glare = 0.0; @@ -643,7 +720,8 @@ void main() col += spec_contrib; } - col = mix(col.rgb, old_diffcol.rgb, diffuse.a); + + col = mix(col.rgb, diffcol.rgb, diffuse.a); if (envIntensity > 0.0) { @@ -661,16 +739,20 @@ void main() glare += cur_glare; } - col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); - col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); + //col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); + //col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); - //convert to linear space before adding local lights - col = pow(col, vec3(2.2)); + col = atmosLighting(col); + col = scaleSoftClip(col); + //convert to linear space before adding local lights + col = srgb_to_linear(col); vec3 npos = normalize(-pos.xyz); - #define LIGHT_LOOP(i) col.rgb = col.rgb + calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare); + vec3 light = vec3(0,0,0); + + #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare); LIGHT_LOOP(1) LIGHT_LOOP(2) @@ -680,13 +762,22 @@ void main() LIGHT_LOOP(6) LIGHT_LOOP(7) + col.rgb += light.rgb; + + glare = min(glare, 1.0); + float al = max(diffcol.a,glare)*vertex_color.a; //convert to gamma space for display on screen - col.rgb = pow(col.rgb, vec3(1.0/2.2)); + col.rgb = linear_to_srgb(col.rgb); + +#ifdef WATER_FOG + vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al)); + col.rgb = temp.rgb; + al = temp.a; +#endif frag_color.rgb = col.rgb; - glare = min(glare, 1.0); - frag_color.a = max(diffcol.a,glare)*vertex_color.a; + frag_color.a = al; #else frag_data[0] = final_color; @@ -694,3 +785,4 @@ void main() frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity. #endif } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index b25032866b..393d1e69da 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -142,3 +142,4 @@ vary_normal = n; #endif #endif } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 868526d457..3ba6de8b76 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -45,9 +45,8 @@ 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]; +uniform vec4 light[LIGHT_COUNT]; +uniform vec4 light_col[LIGHT_COUNT]; VARYING vec4 vary_fragcoord; uniform vec2 screen_res; @@ -56,22 +55,6 @@ uniform float far_z; uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -88,7 +71,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif vec4 getPosition(vec2 pos_screen) { @@ -117,78 +99,66 @@ void main() norm = normalize(norm); vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; + float noise = texture2D(noiseMap, frag.xy/128.0).b; vec3 out_col = vec3(0,0,0); vec3 npos = normalize(-pos); // 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) + for (int i = 0; i < LIGHT_COUNT; ++i) { - bool light_contrib = (i < light_count); - vec3 lv = light[i].xyz-pos; float dist = length(lv); dist /= light[i].w; - if (dist > 1.0) + if (dist <= 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 da = dot(norm, lv); + if (da > 0.0) + { + lv = normalize(lv); + da = dot(norm, lv); - float fa = light_col[i].a+1.0; - float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); - dist_atten *= dist_atten; - dist_atten *= 2.0; + float fa = light_col[i].a+1.0; + float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); + dist_atten *= dist_atten; + dist_atten *= 2.0; - dist_atten *= noise; + dist_atten *= noise; - float lit = da * dist_atten; + float lit = da * dist_atten; - vec3 col = light_col[i].rgb*lit*diff; + vec3 col = light_col[i].rgb*lit*diff; - //vec3 col = vec3(dist2, light_col[i].a, lit); + //vec3 col = vec3(dist2, light_col[i].a, lit); - if (spec.a > 0.0) - { - lit = min(da*6.0, 1.0) * dist_atten; - //vec3 ref = dot(pos+lv, norm); - vec3 h = normalize(lv+npos); - float nh = dot(norm, h); - float nv = dot(norm, npos); - float vh = dot(npos, h); - float sa = nh; - float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; - - float gtdenom = 2 * nh; - float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); - - if (nh > 0.0) + if (spec.a > 0.0) { - float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); - col += lit*scol*light_col[i].rgb*spec.rgb; - //col += spec.rgb; + lit = min(da*6.0, 1.0) * dist_atten; + //vec3 ref = dot(pos+lv, norm); + vec3 h = normalize(lv+npos); + float nh = dot(norm, h); + float nv = dot(norm, npos); + float vh = dot(npos, h); + float sa = nh; + float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + + float gtdenom = 2 * nh; + float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); + + if (nh > 0.0) + { + float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); + col += lit*scol*light_col[i].rgb*spec.rgb; + //col += spec.rgb; + } } - } - out_col += col; + out_col += col; + } } } - if (dot(out_col, out_col) <= 0.0) - { - discard; - } - + frag_color.rgb = out_col; frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 97bf49a605..0e6ab80d4d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -32,6 +32,7 @@ out vec4 frag_color; //class 1 -- no shadows #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; @@ -67,22 +68,6 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -99,17 +84,48 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); #endif -vec4 correctWithGamma(vec4 col) +} + +vec3 linear_to_srgb(vec3 cl) { - return vec4(pow(col.rgb, vec3(2.2)), col.a); + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); +#endif + } + vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) { vec4 ret = texture2DLod(projectionMap, tc, lod); - ret = correctWithGamma(ret); + ret.rgb = srgb_to_linear(ret.rgb); vec2 dist = tc-vec2(0.5); @@ -125,7 +141,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) { vec4 ret = texture2DLod(projectionMap, tc, lod); - ret = correctWithGamma(ret); + ret.rgb = srgb_to_linear(ret.rgb); vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -143,7 +159,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) { vec4 ret = texture2DLod(projectionMap, tc, lod); - ret = correctWithGamma(ret); + ret.rgb = srgb_to_linear(ret.rgb); vec2 dist = tc-vec2(0.5); @@ -295,14 +311,11 @@ void main() vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); - + stc /= stc.w; if (stc.z > 0.0) { - stc.xy /= stc.w; - - float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); + float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0); - //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); if (stc.x < 1.0 && @@ -310,7 +323,7 @@ void main() stc.x > 0.0 && stc.y > 0.0) { - col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb; + col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb; } } } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index caf20ce707..106d48bd71 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -54,22 +54,6 @@ uniform vec2 screen_res; uniform mat4 inv_proj; uniform vec4 viewport; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -86,7 +70,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 6f2cfae6d2..4e2f98aa29 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -36,11 +36,32 @@ uniform sampler2DRect diffuseRect; uniform vec2 screen_res; VARYING vec2 vary_fragcoord; -uniform float texture_gamma; +uniform float display_gamma; + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); +#endif + +} + void main() { vec4 diff = texture2DRect(diffuseRect, vary_fragcoord); - frag_color = pow(diff, vec4(texture_gamma, texture_gamma, texture_gamma, 1.0f)); + diff.rgb = linear_to_srgb(diff.rgb); + frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 08583ad0f2..760d52a9ce 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; @@ -78,22 +79,43 @@ vec3 vary_AtmosAttenuation; uniform mat4 inv_proj; uniform vec2 screen_res; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) +vec3 srgb_to_linear(vec3 cs) { - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + } -vec3 decode_normal (vec2 enc) +vec3 linear_to_srgb(vec3 cl) { - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; #else + return mix(high_range, low_range, lt); +#endif + +} + + vec3 decode_normal (vec2 enc) { vec2 fenc = enc*4-2; @@ -104,7 +126,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif vec4 getPosition_d(vec2 pos_screen, float depth) { @@ -170,6 +191,53 @@ void setAtmosAttenuation(vec3 v) vary_AtmosAttenuation = v; } + +#ifdef WATER_FOG +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec4 applyWaterFogDeferred(vec3 pos, vec4 color) +{ + //normalize view vector + vec3 view = normalize(pos); + float es = -(dot(view, waterPlane.xyz)); + + //find intersection point with water plane and eye vector + + //get eye depth + float e0 = max(-waterPlane.w, 0.0); + + vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); + + //get object depth + float depth = length(pos - int_v); + + //get "thickness" of water + float l = max(depth, 0.1); + + float kd = waterFogDensity; + float ks = waterFogKS; + vec4 kc = waterFogColor; + + float F = 0.98; + + float t1 = -kd * pow(F, ks * e0); + float t2 = kd + ks * es; + float t3 = pow(F, t2*l) - 1.0; + + float L = min(t1/t2*t3, 1.0); + + float D = pow(0.98, l*kd); + + color.rgb = color.rgb * D + kc.rgb * L; + color.a = kc.a + color.a; + + return color; +} +#endif + void calcAtmospherics(vec3 inPositionEye, float ambFactor) { vec3 P = inPositionEye; @@ -324,13 +392,16 @@ void main() float envIntensity = norm.z; norm.xyz = decode_normal(norm.xy); // unpack norm - float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); - da = pow(da, 1.0/1.3); + float da = dot(norm.xyz, sun_dir.xyz); + + float final_da = max(0.0,da); + final_da = min(final_da, 1.0f); + final_da = pow(final_da, 1.0/1.3); vec4 diffuse = texture2DRect(diffuseRect, tc); //convert to gamma space - diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2)); + diffuse.rgb = linear_to_srgb(diffuse.rgb); vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); vec3 col; @@ -346,7 +417,7 @@ void main() col.rgb *= ambient; - col += atmosAffectDirectionalLight(max(min(da, 1.0), 0.0)); + col += atmosAffectDirectionalLight(final_da); col *= diffuse.rgb; @@ -386,13 +457,19 @@ void main() col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); } - col = pow(col, vec3(2.2)); + #ifdef WATER_FOG + vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom)); + col = fogged.rgb; + bloom = fogged.a; + #endif + + col = srgb_to_linear(col); //col = vec3(1,0,1); //col.g = envIntensity; } - frag_color.rgb = col; - + frag_color.rgb = col.rgb; frag_color.a = bloom; } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 1975b18652..2020e8691b 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; @@ -31,6 +32,8 @@ out vec4 frag_color; #define frag_color gl_FragColor #endif +//class 1 -- no shadows + uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect depthMap; @@ -65,22 +68,6 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -97,11 +84,47 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } + +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); #endif +} + vec4 correctWithGamma(vec4 col) { - return vec4(pow(col.rgb, vec3(2.2)), col.a); + return vec4(srgb_to_linear(col.rgb), col.a); } vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl new file mode 100644 index 0000000000..587f3d5a94 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl @@ -0,0 +1,46 @@ +/** + * @file srgb.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + return mix(high_range, low_range, lte); + +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + + bvec3 lt = lessThan(cl,vec3(0.0031308)); + return mix(high_range, low_range, lt); + +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl new file mode 100644 index 0000000000..6cc1e6e798 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl @@ -0,0 +1,54 @@ +/** + * @file srgb.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + + bvec3 lt = lessThan(cl,vec3(0.0031308)); + + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 6653f57ee1..c0a5865bef 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -49,22 +49,6 @@ VARYING vec2 vary_fragcoord; uniform mat4 inv_proj; uniform vec2 screen_res; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -81,7 +65,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl new file mode 100644 index 0000000000..78f841c733 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl @@ -0,0 +1,157 @@ +/** + * @file underWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif + +uniform sampler2D diffuseMap; +uniform sampler2D bumpMap; +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform sampler2D screenDepth; + +uniform vec4 fogCol; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform vec2 fbScale; +uniform float refScale; +uniform float znear; +uniform float zfar; +uniform float kd; +uniform vec4 waterPlane; +uniform vec3 eyeVec; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; +uniform vec2 screenRes; + +//bigWave is (refCoord.w, view.w); +VARYING vec4 refCoord; +VARYING vec4 littleWave; +VARYING vec4 view; + +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); +#endif + +} + +vec2 encode_normal(vec3 n) +{ + float f = sqrt(8 * n.z + 8); + return n.xy / f + 0.5; +} + +vec4 applyWaterFog(vec4 color, vec3 viewVec) +{ + //normalize view vector + vec3 view = normalize(viewVec); + float es = -view.z; + + //find intersection point with water plane and eye vector + + //get eye depth + float e0 = max(-waterPlane.w, 0.0); + + //get object depth + float depth = length(viewVec); + + //get "thickness" of water + float l = max(depth, 0.1); + + float kd = waterFogDensity; + float ks = waterFogKS; + vec4 kc = waterFogColor; + + float F = 0.98; + + float t1 = -kd * pow(F, ks * e0); + float t2 = kd + ks * es; + float t3 = pow(F, t2*l) - 1.0; + + float L = min(t1/t2*t3, 1.0); + + float D = pow(0.98, l*kd); + //return vec4(1.0, 0.0, 1.0, 1.0); + return color * D + kc * L; + //depth /= 10.0; + //return vec4(depth,depth,depth,0.0); +} + +void main() +{ + vec4 color; + + //get detail normals + vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; + vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; + vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; + vec3 wavef = normalize(wave1+wave2+wave3); + + //figure out distortion vector (ripply) + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + distort = distort+wavef.xy*refScale; + + vec4 fb = texture2D(screenTex, distort); + + frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse + frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec + frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index daa2fb390a..72c46e240d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -67,6 +67,43 @@ VARYING vec4 littleWave; VARYING vec4 view; VARYING vec4 vary_position; +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); +#endif + +} + vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -121,7 +158,7 @@ void main() refcol *= df1 * 0.333; vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; - //wavef.z *= max(-viewVec.z, 0.1); + wavef.z *= max(-viewVec.z, 0.1); wavef = normalize(wavef); float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; @@ -131,13 +168,14 @@ void main() vec2 refvec4 = distort+refdistort4/dmod; float dweight = min(dist2*blurMultiplier, 1.0); vec4 baseCol = texture2D(refTex, refvec4); + refcol = mix(baseCol*df2, refcol, dweight); //get specular component - //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); + float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); //harden specular - //spec = pow(spec, 128.0); + spec = pow(spec, 128.0); //figure out distortion vector (ripply) vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); @@ -148,24 +186,17 @@ void main() // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); - float shadow = 1.0; vec4 pos = vary_position; - - //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - vec4 spos = pos; - //spec *= shadow; - //color.rgb += spec * specular; - + color.rgb += spec * specular; + color.rgb = atmosTransport(color.rgb); color.rgb = scaleSoftClip(color.rgb); - //color.a = spec * sunAngle2; + color.a = spec * sunAngle2; - //wavef.z *= 0.1f; - //wavef = normalize(wavef); - vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; + vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz); - frag_data[0] = vec4(color.rgb, 0.5); // diffuse - frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec - frag_data[2] = vec4(encode_normal(screenspacewavef), 0.0, 0.0); // normalxyz, displace + frag_data[0] = vec4(color.rgb, color); // diffuse + frag_data[1] = vec4(0); // speccolor, spec + frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0 } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl index ece34dcc4e..9734acf005 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl @@ -85,7 +85,7 @@ void main() pos.w = 1.0; pos = modelview_matrix*pos; - calcAtmospherics(view.xyz); + calcAtmospherics(pos.xyz); //pass wave parameters to pixel shader vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl index 6523a06d22..f8efd7cb4a 100644 --- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl @@ -31,8 +31,6 @@ out vec4 frag_color; uniform sampler2D depthMap; -uniform float delta; - VARYING vec2 tc0; VARYING vec2 tc1; VARYING vec2 tc2; diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl index 0e5dc08183..942c5888e7 100644 --- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl @@ -33,8 +33,6 @@ out vec4 frag_color; uniform sampler2DRect depthMap; -uniform float delta; - VARYING vec2 tc0; VARYING vec2 tc1; VARYING vec2 tc2; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl index eaaa7b208d..cad5b9ff04 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl @@ -41,13 +41,13 @@ void default_lighting() { vec4 color = diffuseLookup(vary_texcoord0.xy); + color *= vertex_color; + if (color.a < minimum_alpha) { discard; } - color.rgb *= vertex_color.rgb; - color.rgb = atmosLighting(color.rgb); color.rgb = scaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl deleted file mode 100755 index 13c6ffc607..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file alphaV.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -uniform mat3 normal_matrix; -uniform mat4 texture_matrix0; -uniform mat4 projection_matrix; -uniform mat4 modelview_matrix; -uniform mat4 modelview_projection_matrix; - -ATTRIBUTE vec3 position; - -#ifdef USE_INDEXED_TEX -void passTextureIndex(); -#endif - -ATTRIBUTE vec3 normal; - -#ifdef USE_VERTEX_COLOR -ATTRIBUTE vec4 diffuse_color; -#endif - -ATTRIBUTE vec2 texcoord0; - -#ifdef HAS_SKIN -mat4 getObjectSkinnedTransform(); -#else -#ifdef IS_AVATAR_SKIN -mat4 getSkinnedTransform(); -#endif -#endif - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -void calcAtmospherics(vec3 inPositionEye); - -vec3 calcDirectionalLight(vec3 n, vec3 l); - -vec3 atmosAmbient(vec3 light); -vec3 atmosAffectDirectionalLight(float lightIntensity); -vec3 scaleDownLight(vec3 light); -vec3 scaleUpLight(vec3 light); - -VARYING vec3 vary_ambient; -VARYING vec3 vary_directional; -VARYING vec3 vary_fragcoord; -VARYING vec3 vary_position; -VARYING vec3 vary_pointlight_col; - -#ifdef USE_VERTEX_COLOR -VARYING vec4 vertex_color; -#endif - -VARYING vec2 vary_texcoord0; -VARYING vec3 vary_norm; - -uniform float near_clip; -uniform float shadow_offset; -uniform float shadow_bias; - -uniform vec4 light_position[8]; -uniform vec3 light_direction[8]; -uniform vec3 light_attenuation[8]; -uniform vec3 light_diffuse[8]; - -uniform vec3 sun_dir; - -vec3 calcDirectionalLight(vec3 n, vec3 l) -{ - float a = max(dot(n,l),0.0); - return vec3(a,a,a); -} - -vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) -{ - //get light vector - vec3 lv = lp.xyz-v; - - //get distance - float d = dot(lv,lv); - - float da = 0.0; - - if (d > 0.0 && la > 0.0 && fa > 0.0) - { - //normalize light vector - lv = normalize(lv); - - //distance attenuation - float dist2 = d/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 - - //angular attenuation - da *= max(dot(n, lv), 0.0); - } - - return vec3(da,da,da); -} - -void main() -{ - vec4 pos; - vec3 norm; - - //transform vertex -#ifdef HAS_SKIN - mat4 trans = getObjectSkinnedTransform(); - trans = modelview_matrix * trans; - - pos = trans * vec4(position.xyz, 1.0); - - norm = position.xyz + normal.xyz; - norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz); - vec4 frag_pos = projection_matrix * pos; - gl_Position = frag_pos; -#else - -#ifdef IS_AVATAR_SKIN - mat4 trans = getSkinnedTransform(); - vec4 pos_in = vec4(position.xyz, 1.0); - pos.x = dot(trans[0], pos_in); - pos.y = dot(trans[1], pos_in); - pos.z = dot(trans[2], pos_in); - pos.w = 1.0; - - norm.x = dot(trans[0].xyz, normal); - norm.y = dot(trans[1].xyz, normal); - norm.z = dot(trans[2].xyz, normal); - norm = normalize(norm); - - vec4 frag_pos = projection_matrix * pos; - gl_Position = frag_pos; -#else - norm = normalize(normal_matrix * normal); - vec4 vert = vec4(position.xyz, 1.0); - pos = (modelview_matrix * vert); - gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); -#endif - -#endif - -#ifdef USE_INDEXED_TEX - passTextureIndex(); - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -#else - vary_texcoord0 = texcoord0; -#endif - - vary_norm = norm; - float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz)); - vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset; - - calcAtmospherics(pos.xyz); - -#ifndef USE_VERTEX_COLOR - vec4 diffuse_color = vec4(1,1,1,1); -#endif - - //vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.)); - vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); - - vec3 dff = pow(diffuse_color.rgb, vec3(2.2f,2.2f,2.2f)); - - vary_pointlight_col = dff; - - col.rgb = vec3(0,0,0); - - // Add windlight lights - col.rgb = atmosAmbient(col.rgb); - - float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); - ambient *= 0.5; - ambient *= ambient; - ambient = (1.0-ambient); - - col.rgb *= ambient; - - vary_directional.rgb = atmosAffectDirectionalLight(1.0f); - vary_ambient = col.rgb*dff; - - col.rgb = col.rgb*dff; - -#ifdef USE_VERTEX_COLOR - vertex_color = col; -#endif - -#ifdef HAS_SKIN - vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); -#else - -#ifdef IS_AVATAR_SKIN - vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); -#else - pos = modelview_projection_matrix * vert; - vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); -#endif - -#endif - -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 780df9ed1a..c20e00163c 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; @@ -68,22 +69,43 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) +vec3 srgb_to_linear(vec3 cs) { - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + } -vec3 decode_normal (vec2 enc) +vec3 linear_to_srgb(vec3 cl) { - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; #else + return mix(high_range, low_range, lt); +#endif + +} + vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -100,14 +122,12 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif vec4 correctWithGamma(vec4 col) { - return vec4(pow(col.rgb, vec3(2.2)), col.a); + return vec4(srgb_to_linear(col.rgb), col.a); } - vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) { vec4 ret = texture2DLod(projectionMap, tc, lod); @@ -314,14 +334,12 @@ void main() vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + stc /= stc.w; if (stc.z > 0.0) { - stc.xy /= stc.w; + float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0); - float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); - - //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); if (stc.x < 1.0 && @@ -329,12 +347,16 @@ void main() stc.x > 0.0 && stc.y > 0.0) { - col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb; + col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*shadow*spec.rgb; } } } } + + //not sure why, but this line prevents MATBUG-194 + col = max(col, vec3(0.0)); + frag_color.rgb = col; frag_color.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 67bac1f7c2..cc34285d65 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -78,22 +78,43 @@ vec3 vary_AtmosAttenuation; uniform mat4 inv_proj; uniform vec2 screen_res; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) +vec3 srgb_to_linear(vec3 cs) { - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + } -vec3 decode_normal (vec2 enc) +vec3 linear_to_srgb(vec3 cl) { - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; #else + return mix(high_range, low_range, lt); +#endif + +} + vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -110,7 +131,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif vec4 getPosition_d(vec2 pos_screen, float depth) { @@ -263,6 +283,52 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); } +#ifdef WATER_FOG +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec4 applyWaterFogDeferred(vec3 pos, vec4 color) +{ + //normalize view vector + vec3 view = normalize(pos); + float es = -(dot(view, waterPlane.xyz)); + + //find intersection point with water plane and eye vector + + //get eye depth + float e0 = max(-waterPlane.w, 0.0); + + vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); + + //get object depth + float depth = length(pos - int_v); + + //get "thickness" of water + float l = max(depth, 0.1); + + float kd = waterFogDensity; + float ks = waterFogKS; + vec4 kc = waterFogColor; + + float F = 0.98; + + float t1 = -kd * pow(F, ks * e0); + float t2 = kd + ks * es; + float t3 = pow(F, t2*l) - 1.0; + + float L = min(t1/t2*t3, 1.0); + + float D = pow(0.98, l*kd); + + color.rgb = color.rgb * D + kc.rgb * L; + color.a = kc.a + color.a; + + return color; +} +#endif + vec3 atmosLighting(vec3 light) { light *= getAtmosAttenuation().r; @@ -343,7 +409,7 @@ void main() vec4 diffuse = texture2DRect(diffuseRect, tc); //convert to gamma space - diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2)); + diffuse.rgb = linear_to_srgb(diffuse.rgb); vec3 col; float bloom = 0.0; @@ -402,19 +468,25 @@ void main() envIntensity); } - + if (norm.w < 0.5) { col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); } - col = pow(col, vec3(2.2)); + #ifdef WATER_FOG + vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom)); + col = fogged.rgb; + bloom = fogged.a; + #endif + + col = srgb_to_linear(col); //col = vec3(1,0,1); //col.g = envIntensity; } - + frag_color.rgb = col; frag_color.a = bloom; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index fc0e6b2388..7689b72d20 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -24,6 +24,7 @@ */ #extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; @@ -68,22 +69,6 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -100,11 +85,47 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } + +vec3 srgb_to_linear(vec3 cs) +{ + vec3 low_range = cs / vec3(12.92); + vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); + bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lte); +#endif + +} + +vec3 linear_to_srgb(vec3 cl) +{ + cl = clamp(cl, vec3(0), vec3(1)); + vec3 low_range = cl * 12.92; + vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055; + bvec3 lt = lessThan(cl,vec3(0.0031308)); + +#ifdef OLD_SELECT + vec3 result; + result.r = lt.r ? low_range.r : high_range.r; + result.g = lt.g ? low_range.g : high_range.g; + result.b = lt.b ? low_range.b : high_range.b; + return result; +#else + return mix(high_range, low_range, lt); #endif +} + vec4 correctWithGamma(vec4 col) { - return vec4(pow(col.rgb, vec3(2.2)), col.a); + return vec4(srgb_to_linear(col.rgb), col.a); } vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) @@ -333,6 +354,9 @@ void main() } } + //not sure why, but this line prevents MATBUG-194 + col = max(col, vec3(0.0)); + frag_color.rgb = col; frag_color.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 7b09dd29dd..95c09d3238 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -65,22 +65,6 @@ uniform float shadow_offset; uniform float spot_shadow_bias; uniform float spot_shadow_offset; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -97,7 +81,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 01e34ed792..b5ff6404ea 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -66,22 +66,6 @@ uniform float shadow_offset; uniform float spot_shadow_bias; uniform float spot_shadow_offset; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ - vec2 sn; - sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); - return sn; -} - -vec3 decode_normal (vec2 enc) -{ - vec3 n; - n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); - n.z = sqrt(1.0f - dot(n.xy,n.xy)); - return n; -} -#else vec2 encode_normal(vec3 n) { float f = sqrt(8 * n.z + 8); @@ -98,7 +82,6 @@ vec3 decode_normal (vec2 enc) n.z = 1-f/2; return n; } -#endif vec4 getPosition(vec2 pos_screen) { diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 1c0d45c11b..0bdd425504 100755 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -309,8 +309,8 @@ RenderVolumeLODFactor 1 2.0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 RenderFSAASamples 1 2 diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm new file mode 100644 index 0000000000..30476b3d22 --- /dev/null +++ b/indra/newview/llappdelegate-objc.mm @@ -0,0 +1,144 @@ +/** + * @file llappdelegate-objc.mm + * @brief Class implementation for the Mac version's application delegate. + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#import "llappdelegate-objc.h" +#include "llwindowmacosx-objc.h" +#include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported) + +@implementation LLAppDelegate + +@synthesize window; +@synthesize inputWindow; +@synthesize inputView; +@synthesize currentInputLanguage; + +- (void)dealloc +{ + [super dealloc]; +} + +- (void) applicationDidFinishLaunching:(NSNotification *)notification +{ + frameTimer = nil; + + [self languageUpdated]; + + if (initViewer()) + { + frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; + } else { + handleQuit(); + } + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil]; +} + +- (void) applicationDidBecomeActive:(NSNotification *)notification +{ + callWindowFocus(); +} + +- (void) applicationDidResignActive:(NSNotification *)notification +{ + callWindowUnfocus(); +} + +- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender +{ + if (!runMainLoop()) + { + handleQuit(); + return NSTerminateCancel; + } else { + [frameTimer release]; + cleanupViewer(); + return NSTerminateNow; + } +} + +- (void) mainLoop +{ + bool appExiting = runMainLoop(); + if (appExiting) + { + [frameTimer release]; + [[NSApplication sharedApplication] terminate:self]; + } +} + +- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent +{ + if (![self romanScript]) + { + if (show) + { + NSLog(@"Showing input window."); + [inputWindow makeKeyAndOrderFront:inputWindow]; + if (textEvent != nil) + { + [[inputView inputContext] discardMarkedText]; + [[inputView inputContext] handleEvent:textEvent]; + } + } else { + NSLog(@"Hiding input window."); + [inputWindow orderOut:inputWindow]; + [window makeKeyAndOrderFront:window]; + } + } +} + +// This will get called multiple times by NSNotificationCenter. +// It will be called every time that the window focus changes, and every time that the input language gets changed. +// The primary use case for this selector is to update our current input language when the user, for whatever reason, changes the input language. +// This is the more elegant way of handling input language changes instead of checking every time we want to use the input window. + +- (void) languageUpdated +{ + TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource(); + CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages); + +#if 0 // In the event of ever needing to add new language sources, change this to 1 and watch the terminal for "languages:" + NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages)); +#endif + + // Typically the language we want is going to be the very first result in the array. + currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0); +} + +- (bool) romanScript +{ + // How to add support for new languages with the input window: + // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) + NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil]; + if ([nonRomanScript containsObject:currentInputLanguage]) + { + return false; + } + + return true; +} + +@end diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 003d82dd0e..02eb67bf80 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -723,6 +723,11 @@ bool LLAppViewer::init() // we run the "program crashed last time" error handler below. // LLFastTimer::reset(); + + +#ifdef LL_DARWIN + mMainLoopInitialized = false; +#endif // initialize LLWearableType translation bridge. // Memory will be cleaned up in ::cleanupClass() @@ -1253,40 +1258,57 @@ LLFastTimer::DeclareTimer FTM_FRAME("Frame", true); bool LLAppViewer::mainLoop() { - mMainloopTimeout = new LLWatchdogTimeout(); +#ifdef LL_DARWIN + if (!mMainLoopInitialized) +#endif + { + mMainloopTimeout = new LLWatchdogTimeout(); + + //------------------------------------------- + // Run main loop until time to quit + //------------------------------------------- + + // Create IO Pump to use for HTTP Requests. + gServicePump = new LLPumpIO(gAPRPoolp); + LLHTTPClient::setPump(*gServicePump); + LLCurl::setCAFile(gDirUtilp->getCAFile()); + + // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. + + LLVoiceChannel::initClass(); + LLVoiceClient::getInstance()->init(gServicePump); + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); + + joystick = LLViewerJoystick::getInstance(); + joystick->setNeedsReset(true); + +#ifdef LL_DARWIN + // Ensure that this section of code never gets called again on OS X. + mMainLoopInitialized = true; +#endif + } + // As we do not (yet) send data on the mainloop LLEventPump that varies + // with each frame, no need to instantiate a new LLSD event object each + // time. Obviously, if that changes, just instantiate the LLSD at the + // point of posting. + + LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); + + LLSD newFrame; - //------------------------------------------- - // Run main loop until time to quit - //------------------------------------------- - - // Create IO Pump to use for HTTP Requests. - gServicePump = new LLPumpIO(gAPRPoolp); - LLHTTPClient::setPump(*gServicePump); - LLCurl::setCAFile(gDirUtilp->getCAFile()); - - // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. - - LLVoiceChannel::initClass(); - LLVoiceClient::getInstance()->init(gServicePump); - LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); LLTimer frameTimer,idleTimer; LLTimer debugTime; - LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); - joystick->setNeedsReset(true); - - LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); - // As we do not (yet) send data on the mainloop LLEventPump that varies - // with each frame, no need to instantiate a new LLSD event object each - // time. Obviously, if that changes, just instantiate the LLSD at the - // point of posting. - LLSD newFrame; - + //LLPrivateMemoryPoolTester::getInstance()->run(false) ; //LLPrivateMemoryPoolTester::getInstance()->run(true) ; //LLPrivateMemoryPoolTester::destroy() ; // Handle messages +#ifdef LL_DARWIN + if (!LLApp::isExiting()) +#else while (!LLApp::isExiting()) +#endif { LLFastTimer _(FTM_FRAME); LLFastTimer::nextFrame(); @@ -1562,34 +1584,37 @@ bool LLAppViewer::mainLoop() } } - // Save snapshot for next time, if we made it through initialization - if (STATE_STARTED == LLStartUp::getStartupState()) + if (LLApp::isExiting()) { - try - { - saveFinalSnapshot(); - } - catch(std::bad_alloc) + // Save snapshot for next time, if we made it through initialization + if (STATE_STARTED == LLStartUp::getStartupState()) { - llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ; - - //stop memory leaking simulation - LLFloaterMemLeak* mem_leak_instance = - LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); - if(mem_leak_instance) + try { - mem_leak_instance->stop() ; - } + saveFinalSnapshot(); + } + catch(std::bad_alloc) + { + llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ; + + //stop memory leaking simulation + LLFloaterMemLeak* mem_leak_instance = + LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); + if(mem_leak_instance) + { + mem_leak_instance->stop() ; + } + } } + + delete gServicePump; + + destroyMainloopTimeout(); + + llinfos << "Exiting main_loop" << llendflush; } - - delete gServicePump; - - destroyMainloopTimeout(); - - llinfos << "Exiting main_loop" << llendflush; - return true; + return LLApp::isExiting(); } void LLAppViewer::flushVFSIO() @@ -2667,8 +2692,6 @@ bool LLAppViewer::initConfiguration() //} #if LL_DARWIN - // Initialize apple menubar and various callbacks - init_apple_menu(LLTrans::getString("APP_NAME").c_str()); #if __ppc__ // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further. diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 3af360b529..3ae8a78845 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -42,6 +42,7 @@ class LLImageDecodeThread; class LLTextureFetch; class LLWatchdogTimeout; class LLUpdaterService; +class LLViewerJoystick; extern LLFastTimer::DeclareTimer FTM_FRAME; @@ -255,6 +256,8 @@ private: std::string mSerialNumber; bool mPurgeCache; bool mPurgeOnExit; + bool mMainLoopInitialized; + LLViewerJoystick* joystick; bool mSavedFinalSnapshot; bool mSavePerAccountSettings; // only save per account settings if login succeeded diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index c7b437598c..316c90d9d2 100755 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -30,7 +30,10 @@ #error "Use only with Mac OS X" #endif +#define LL_CARBON_CRASH_HANDLER 1 + #include "llappviewermacosx.h" +#include "llwindowmacosx-objc.h" #include "llcommandlineparser.h" #include "llviewernetwork.h" @@ -38,7 +41,10 @@ #include "llmd5.h" #include "llfloaterworldmap.h" #include "llurldispatcher.h" +#include <ApplicationServices/ApplicationServices.h> +#ifdef LL_CARBON_CRASH_HANDLER #include <Carbon/Carbon.h> +#endif #include "lldir.h" #include <signal.h> #include <CoreAudio/CoreAudio.h> // for systemwide mute @@ -50,9 +56,9 @@ namespace // They are not used immediately by the app. int gArgC; char** gArgV; - bool sCrashReporterIsRunning = false; - + LLAppViewerMacOSX* gViewerAppPtr; +#ifdef LL_CARBON_CRASH_HANDLER OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) { OSErr result = noErr; @@ -61,9 +67,10 @@ namespace return(result); } +#endif } -int main( int argc, char **argv ) +bool initViewer() { #if LL_SOLARIS && defined(__sparc) asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC @@ -73,43 +80,60 @@ int main( int argc, char **argv ) if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1) { llwarns << "Could not change directory to " - << gDirUtilp->getAppRODataDir() << ": " << strerror(errno) - << llendl; + << gDirUtilp->getAppRODataDir() << ": " << strerror(errno) + << llendl; } - - LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX(); - - viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); - - // Store off the command line args for use later. - gArgC = argc; - gArgV = argv; - bool ok = viewer_app_ptr->init(); + gViewerAppPtr = new LLAppViewerMacOSX(); + + gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash); + + + + bool ok = gViewerAppPtr->init(); if(!ok) { llwarns << "Application init failed." << llendl; - return -1; } + + return ok; +} - // Run the application main loop - if(!LLApp::isQuitting()) +void handleQuit() +{ + LLAppViewer::instance()->userQuit(); +} + +bool runMainLoop() +{ + bool ret = LLApp::isQuitting(); + if (!ret && gViewerAppPtr != NULL) { - viewer_app_ptr->mainLoop(); + ret = gViewerAppPtr->mainLoop(); + } else { + ret = true; } + + return ret; +} - if (!LLApp::isError()) +void cleanupViewer() +{ + if(!LLApp::isError()) { - // - // We don't want to do cleanup here if the error handler got called - - // the assumption is that the error handler is responsible for doing - // app cleanup if there was a problem. - // - viewer_app_ptr->cleanup(); + gViewerAppPtr->cleanup(); } - delete viewer_app_ptr; - viewer_app_ptr = NULL; - return 0; + + delete gViewerAppPtr; + gViewerAppPtr = NULL; +} + +int main( int argc, char **argv ) +{ + // Store off the command line args for use later. + gArgC = argc; + gArgV = argv; + return createNSApp(argc, (const char**)argv); } LLAppViewerMacOSX::LLAppViewerMacOSX() @@ -239,23 +263,24 @@ bool LLAppViewerMacOSX::restoreErrorTrap() return reset_count == 0; } -static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, - EventRef inEvent, +#ifdef LL_CARBON_CRASH_HANDLER +static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, + EventRef inEvent, void* inUserData) { ProcessSerialNumber psn; - GetEventParameter(inEvent, - kEventParamProcessID, - typeProcessSerialNumber, - NULL, - sizeof(psn), - NULL, + GetEventParameter(inEvent, + kEventParamProcessID, + typeProcessSerialNumber, + NULL, + sizeof(psn), + NULL, &psn); - if( GetEventKind(inEvent) == kEventAppTerminated ) + if( GetEventKind(inEvent) == kEventAppTerminated ) { - Boolean matching_psn = FALSE; + Boolean matching_psn = FALSE; OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn); if(os_result >= 0 && matching_psn) { @@ -265,48 +290,58 @@ static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, } return noErr; } +#endif void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) { - // This used to use fork&exec, but is switched to LSOpenApplication to +#ifdef LL_CARBON_CRASH_HANDLER + // This used to use fork&exec, but is switched to LSOpenApplication to // Make sure the crash reporter launches in front of the SL window. std::string command_str; //command_str = "open Second Life.app/Contents/Resources/mac-crash-logger.app"; command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger"; + CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)command_str.c_str(), strlen(command_str.c_str()), FALSE); + + // FSRef apparently isn't deprecated. + // There's other funcitonality that depends on it existing as well that isn't deprecated. + // There doesn't seem to be much to directly verify what the status of FSRef is, outside of some documentation pointing at FSRef being valid, and other documentation pointing to everything in Files.h being deprecated. + // We'll assume it isn't for now, since all non-deprecated functions that use it seem to assume similar. + FSRef appRef; - Boolean isDir = 0; - OSStatus os_result = FSPathMakeRef((UInt8*)command_str.c_str(), - &appRef, - &isDir); - if(os_result >= 0) + Boolean pathstatus = CFURLGetFSRef(urlRef, &appRef); + + OSStatus os_result = noErr; + + if(pathstatus == true) { LSApplicationParameters appParams; memset(&appParams, 0, sizeof(appParams)); appParams.version = 0; appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic; + appParams.application = &appRef; if(reportFreeze) { - // Make sure freeze reporting launches the crash logger synchronously, lest + // Make sure freeze reporting launches the crash logger synchronously, lest // Log files get changed by SL while the logger is running. - + // *NOTE:Mani A better way - make a copy of the data that the crash reporter will send // and let SL go about its business. This way makes the mac work like windows and linux - // and is the smallest patch for the issue. + // and is the smallest patch for the issue. sCrashReporterIsRunning = false; ProcessSerialNumber o_psn; - + static EventHandlerRef sCarbonEventsRef = NULL; - static const EventTypeSpec kEvents[] = + static const EventTypeSpec kEvents[] = { { kEventClassApplication, kEventAppTerminated } }; // Install the handler to detect crash logger termination - InstallEventHandler(GetApplicationEventTarget(), + InstallEventHandler(GetApplicationEventTarget(), (EventHandlerUPP) CarbonEventHandler, GetEventTypeCount(kEvents), kEvents, @@ -314,31 +349,31 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) &sCarbonEventsRef ); - // Remove, temporarily the quit handler - which has *crash* behavior before + // Remove, temporarily the quit handler - which has *crash* behavior before // the mainloop gets running! - AERemoveEventHandler(kCoreEventClass, - kAEQuitApplication, + AERemoveEventHandler(kCoreEventClass, + kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler), false); - + // Launch the crash reporter. os_result = LSOpenApplication(&appParams, &o_psn); if(os_result >= 0) - { + { sCrashReporterIsRunning = true; } - + while(sCrashReporterIsRunning) { RunApplicationEventLoop(); } - + // Re-install the apps quit handler. - AEInstallEventHandler(kCoreEventClass, - kAEQuitApplication, + AEInstallEventHandler(kCoreEventClass, + kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler), - 0, + 0, false); // Remove the crash reporter quit handler. @@ -348,12 +383,12 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) { appParams.flags |= kLSLaunchAsync; clear_signals(); - + ProcessSerialNumber o_psn; os_result = LSOpenApplication(&appParams, &o_psn); } - } +#endif } std::string LLAppViewerMacOSX::generateSerialNumber() @@ -486,73 +521,3 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) return(result); } - -OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) -{ - OSStatus result = eventNotHandledErr; - OSStatus err; - UInt32 evtClass = GetEventClass(event); - UInt32 evtKind = GetEventKind(event); - WindowRef window = (WindowRef)userdata; - - if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess)) - { - HICommand cmd; - err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd); - - if(err == noErr) - { - switch(cmd.commandID) - { - case kHICommandOK: - QuitAppModalLoopForWindow(window); - result = noErr; - break; - - case kHICommandCancel: - QuitAppModalLoopForWindow(window); - result = userCanceledErr; - break; - } - } - } - - return(result); -} - -void init_apple_menu(const char* product) -{ - // Load up a proper menu bar. - { - OSStatus err; - IBNibRef nib = NULL; - // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly. - err = CreateNibReference(CFSTR("SecondLife"), &nib); - - if(err == noErr) - { - // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly. - SetMenuBarFromNib(nib, CFSTR("MenuBar")); - } - - if(nib != NULL) - { - DisposeNibReference(nib); - } - } - - // Install a handler for 'gurl' AppleEvents. This is how secondlife:// URLs get passed to the viewer. - - if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr) - { - // Couldn't install AppleEvent handler. This error shouldn't be fatal. - llinfos << "Couldn't install 'GURL' AppleEvent handler. Continuing..." << llendl; - } - - // Install a handler for 'quit' AppleEvents. This makes quitting the application from the dock work. - if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr) - { - // Couldn't install AppleEvent handler. This error shouldn't be fatal. - llinfos << "Couldn't install Quit AppleEvent handler. Continuing..." << llendl; - } -} diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index d7d9f82910..4c4424edc4 100755 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -37,7 +37,7 @@ #include "llwindow.h" // beforeDialog() #include "llviewercontrol.h" -#if LL_LINUX || LL_SOLARIS +#if LL_LINUX || LL_SOLARIS || LL_DARWIN # include "llfilepicker.h" #endif @@ -147,152 +147,36 @@ std::string LLDirPicker::getDirName() #elif LL_DARWIN LLDirPicker::LLDirPicker() : - mFileName(NULL), - mLocked(false) +mFileName(NULL), +mLocked(false) { + mFilePicker = new LLFilePicker(); reset(); - - memset(&mNavOptions, 0, sizeof(mNavOptions)); - OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions); - if (error == noErr) - { - mNavOptions.modality = kWindowModalityAppModal; - } } LLDirPicker::~LLDirPicker() { - // nothing + delete mFilePicker; } -//static -pascal void LLDirPicker::doNavCallbackEvent(NavEventCallbackMessage callBackSelector, - NavCBRecPtr callBackParms, void* callBackUD) +void LLDirPicker::reset() { - switch(callBackSelector) - { - case kNavCBStart: - { - if (!sInstance.mFileName) break; - - OSStatus error = noErr; - AEDesc theLocation = {typeNull, NULL}; - FSSpec outFSSpec; - - //Convert string to a FSSpec - FSRef myFSRef; - - const char* filename=sInstance.mFileName->c_str(); - - error = FSPathMakeRef ((UInt8*)filename, &myFSRef, NULL); - - if (error != noErr) break; - - error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL); - - if (error != noErr) break; - - error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation); - - if (error != noErr) break; - - error = NavCustomControl(callBackParms->context, - kNavCtlSetLocation, (void*)&theLocation); - - } - } + if (mFilePicker) + mFilePicker->reset(); } -OSStatus LLDirPicker::doNavChooseDialog() -{ - OSStatus error = noErr; - NavDialogRef navRef = NULL; - NavReplyRecord navReply; - - memset(&navReply, 0, sizeof(navReply)); - - // NOTE: we are passing the address of a local variable here. - // This is fine, because the object this call creates will exist for less than the lifetime of this function. - // (It is destroyed by NavDialogDispose() below.) - - error = NavCreateChooseFolderDialog(&mNavOptions, &doNavCallbackEvent, NULL, NULL, &navRef); - - gViewerWindow->getWindow()->beforeDialog(); - - if (error == noErr) - error = NavDialogRun(navRef); - - gViewerWindow->getWindow()->afterDialog(); - - if (error == noErr) - error = NavDialogGetReply(navRef, &navReply); - - if (navRef) - NavDialogDispose(navRef); - - if (error == noErr && navReply.validRecord) - { - FSRef fsRef; - AEKeyword theAEKeyword; - DescType typeCode; - Size actualSize = 0; - char path[LL_MAX_PATH]; /*Flawfinder: ignore*/ - - memset(&fsRef, 0, sizeof(fsRef)); - error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); - - if (error == noErr) - error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path)); - - if (error == noErr) - mDir = path; - } - - return error; -} +//static BOOL LLDirPicker::getDir(std::string* filename) { - if( mLocked ) return FALSE; - BOOL success = FALSE; - OSStatus error = noErr; - - // if local file browsing is turned off, return without opening dialog - if ( check_local_file_access_enabled() == false ) - { - return FALSE; - } - - mFileName = filename; - -// mNavOptions.saveFileName - - // Modal, so pause agent - send_agent_pause(); - { - error = doNavChooseDialog(); - } - send_agent_resume(); - if (error == noErr) - { - if (mDir.length() > 0) - success = true; - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; + LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY; + + return mFilePicker->getOpenFile(filter, true); } std::string LLDirPicker::getDirName() { - return mDir; -} - -void LLDirPicker::reset() -{ - mLocked = false; - mDir.clear(); + return mFilePicker->getFirstFile(); } #elif LL_LINUX || LL_SOLARIS diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index 682f9d6476..9cc62431ef 100755 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -34,11 +34,10 @@ #include "stdtypes.h" #if LL_DARWIN -#include <Carbon/Carbon.h> // AssertMacros.h does bad things. -#include "fix_macros.h" #undef verify +#undef check #undef require #include <vector> @@ -77,15 +76,7 @@ private: void buildDirname( void ); bool check_local_file_access_enabled(); -#if LL_DARWIN - NavDialogCreationOptions mNavOptions; - static pascal void doNavCallbackEvent(NavEventCallbackMessage callBackSelector, - NavCBRecPtr callBackParms, void* callBackUD); - OSStatus doNavChooseDialog(); - -#endif - -#if LL_LINUX || LL_SOLARIS +#if LL_LINUX || LL_SOLARIS || LL_DARWIN // On Linux we just implement LLDirPicker on top of LLFilePicker LLFilePicker *mFilePicker; #endif diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 8c9fd4152a..9682f38227 100755 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -132,10 +132,16 @@ void LLDrawable::destroy() sNumZombieDrawables--; } + // Attempt to catch violations of this in debug, + // knowing that some false alarms may result + // + llassert(!LLSpatialGroup::sNoDelete); + + /* cannot be guaranteed and causes crashes on false alarms if (LLSpatialGroup::sNoDelete) { llerrs << "Illegal deletion of LLDrawable!" << llendl; - } + }*/ std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); mFaces.clear(); @@ -527,6 +533,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) } updatePartition(); } + + llassert(isAvatar() || isRoot() || mParent->isStatic()); } // Returns "distance" between target destination and resulting xfrom diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index c832e1401d..e4ebfea665 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -93,15 +93,35 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) if (pass == 0) { + if (LLPipeline::sImpostorRender) + { + simple_shader = &gDeferredAlphaImpostorProgram; + fullbright_shader = &gDeferredFullbrightProgram; + } + else if (LLPipeline::sUnderWaterRender) + { + simple_shader = &gDeferredAlphaWaterProgram; + fullbright_shader = &gDeferredFullbrightWaterProgram; + } + else + { simple_shader = &gDeferredAlphaProgram; - fullbright_shader = &gObjectFullbrightProgram; + fullbright_shader = &gDeferredFullbrightProgram; + } + + F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + fullbright_shader->bind(); fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); fullbright_shader->unbind(); + //prime simple shader (loads shadow relevant uniforms) gPipeline.bindDeferredShader(*simple_shader); + + simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); } - else + else if (!LLPipeline::sImpostorRender) { //update depth buffer sampler gPipeline.mScreen.flush(); @@ -113,6 +133,23 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f); } + + if (LLPipeline::sRenderDeferred) + { + emissive_shader = &gDeferredEmissiveProgram; + } + else + { + if (LLPipeline::sUnderWaterRender) + { + emissive_shader = &gObjectEmissiveWaterProgram; + } + else + { + emissive_shader = &gObjectEmissiveProgram; + } + } + deferred_render = TRUE; if (mVertexShaderLevel > 0) { @@ -124,7 +161,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) { - if (pass == 1) + if (pass == 1 && !LLPipeline::sImpostorRender) { gPipeline.mDeferredDepth.flush(); gPipeline.mScreen.bindTarget(); @@ -144,7 +181,13 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass) { LLFastTimer t(FTM_RENDER_ALPHA); - if (LLPipeline::sUnderWaterRender) + if (LLPipeline::sImpostorRender) + { + simple_shader = &gObjectSimpleImpostorProgram; + fullbright_shader = &gObjectFullbrightProgram; + emissive_shader = &gObjectEmissiveProgram; + } + else if (LLPipeline::sUnderWaterRender) { simple_shader = &gObjectSimpleWaterProgram; fullbright_shader = &gObjectFullbrightWaterProgram; @@ -192,8 +235,13 @@ void LLDrawPoolAlpha::render(S32 pass) gGL.setColorMask(true, true); } - LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy || - (deferred_render && pass == 1) ? GL_TRUE : GL_FALSE); + bool write_depth = LLDrawPoolWater::sSkipScreenCopy + || (deferred_render && pass == 1) + // we want depth written so that rendered alpha will + // contribute to the alpha mask used for impostors + || LLPipeline::sImpostorRenderAlphaDepthPass; + + LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE); if (deferred_render && pass == 1) { @@ -239,11 +287,11 @@ void LLDrawPoolAlpha::render(S32 pass) if (mVertexShaderLevel > 0) { - renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass); } else { - renderAlpha(getVertexDataMask()); + renderAlpha(getVertexDataMask(), pass); } gGL.setColorMask(true, false); @@ -315,7 +363,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) } } -void LLDrawPoolAlpha::renderAlpha(U32 mask) +void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; @@ -348,11 +396,28 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) continue; } + // Fix for bug - NORSPEC-271 + // If the face is more than 90% transparent, then don't update the Depth buffer for Dof + // We don't want the nearly invisible objects to cause of DoF effects + if(pass == 1 && !LLPipeline::sImpostorRender) + { + LLFace* face = params.mFace; + if(face) + { + const LLTextureEntry* tep = face->getTextureEntry(); + if(tep) + { + if(tep->getColor().mV[3] < 0.1f) + continue; + } + } + } + LLRenderPass::applyModelMatrix(params); LLMaterial* mat = NULL; - if (deferred_render && !LLPipeline::sUnderWaterRender) + if (deferred_render) { mat = params.mMaterial; } @@ -396,6 +461,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) llassert(mask < LLMaterial::SHADER_COUNT); target_shader = &(gDeferredMaterialProgram[mask]); + if (LLPipeline::sUnderWaterRender) + { + target_shader = &(gDeferredMaterialWaterProgram[mask]); + } + if (current_shader != target_shader) { gPipeline.bindDeferredShader(*target_shader); @@ -500,7 +570,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } - params.mVertexBuffer->setBuffer(mask); + params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); + params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); @@ -515,7 +586,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) emissive_shader->bind(); - // glow doesn't use vertex colors from the mesh data params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); // do the actual drawing, again @@ -545,3 +615,4 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) gPipeline.enableLightsDynamic(); } } + diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index 43122218ed..d064a3a324 100755 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -63,7 +63,7 @@ public: /*virtual*/ void prerender(); void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); - void renderAlpha(U32 mask); + void renderAlpha(U32 mask, S32 pass); void renderAlphaHighlight(U32 mask); static BOOL sShowDebugAlpha; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index a0024a231c..66bbc6819b 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -49,6 +49,7 @@ #include "llappviewer.h" #include "llrendersphere.h" #include "llviewerpartsim.h" +#include "llviewercontrol.h" // for gSavedSettings static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK; static U32 sBufferUsage = GL_STREAM_DRAW_ARB; @@ -309,6 +310,11 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) sVertexProgram = &gDeferredMaterialProgram[pass]; + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &(gDeferredMaterialWaterProgram[pass]); + } + gPipeline.bindDeferredShader(*sVertexProgram); sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); @@ -501,7 +507,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses() { if (LLPipeline::sImpostorRender) { - return 3; + return 19; } else { @@ -687,12 +693,10 @@ void LLDrawPoolAvatar::beginDeferredImpostor() } sVertexProgram = &gDeferredImpostorProgram; - specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - - sVertexProgram->bind(); + gPipeline.bindDeferredShader(*sVertexProgram); sVertexProgram->setMinimumAlpha(0.01f); } @@ -702,8 +706,9 @@ void LLDrawPoolAvatar::endDeferredImpostor() sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - sVertexProgram->unbind(); - gGL.getTexUnit(0)->activate(); + gPipeline.unbindDeferredShader(*sVertexProgram); + sVertexProgram = NULL; + sDiffuseChannel = 0; } void LLDrawPoolAvatar::beginDeferredRigid() @@ -891,6 +896,8 @@ void LLDrawPoolAvatar::beginRiggedGlow() sVertexProgram->bind(); sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f); + F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); } } @@ -943,6 +950,9 @@ void LLDrawPoolAvatar::beginRiggedFullbright() else { sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + + F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); } } } @@ -1044,6 +1054,8 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny() else { sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); } } } @@ -1103,6 +1115,12 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) return; } sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT]; + + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]); + } + sVertexProgram->bind(); normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); @@ -1445,63 +1463,63 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) } void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) -{ - face->setGeomIndex(0); - face->setIndicesIndex(0); + { + face->setGeomIndex(0); + face->setIndicesIndex(0); - //rigged faces do not batch textures - face->setTextureIndex(255); + //rigged faces do not batch textures + face->setTextureIndex(255); - if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) - { //make a new buffer - if (sShaderLevel > 0) - { - buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); + if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) + { //make a new buffer + if (sShaderLevel > 0) + { + buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); + } + else + { + buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); + } + buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); } else - { - buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); + { //resize existing buffer + buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices); } - buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); - } - else - { //resize existing buffer - buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices); - } - face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); - face->setVertexBuffer(buffer); + face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); + face->setVertexBuffer(buffer); - U16 offset = 0; + U16 offset = 0; - LLMatrix4 mat_vert = skin->mBindShapeMatrix; - glh::matrix4f m((F32*) mat_vert.mMatrix); - m = m.inverse().transpose(); + LLMatrix4 mat_vert = skin->mBindShapeMatrix; + glh::matrix4f m((F32*) mat_vert.mMatrix); + m = m.inverse().transpose(); - F32 mat3[] = - { m.m[0], m.m[1], m.m[2], - m.m[4], m.m[5], m.m[6], - m.m[8], m.m[9], m.m[10] }; + F32 mat3[] = + { m.m[0], m.m[1], m.m[2], + m.m[4], m.m[5], m.m[6], + m.m[8], m.m[9], m.m[10] }; - LLMatrix3 mat_normal(mat3); + LLMatrix3 mat_normal(mat3); - //let getGeometryVolume know if alpha should override shiny - U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); + //let getGeometryVolume know if alpha should override shiny + U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); - if (type == LLDrawPool::POOL_ALPHA) - { - face->setPoolType(LLDrawPool::POOL_ALPHA); - } - else - { - face->setPoolType(LLDrawPool::POOL_AVATAR); - } + if (type == LLDrawPool::POOL_ALPHA) + { + face->setPoolType(LLDrawPool::POOL_ALPHA); + } + else + { + face->setPoolType(LLDrawPool::POOL_AVATAR); + } //llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl; - face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); + face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); - buffer->flush(); -} + buffer->flush(); + } void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) { diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 08a36bddf1..d1b5080650 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -72,6 +72,12 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass) }; mShader = &(gDeferredMaterialProgram[shader_idx[pass]]); + + if (LLPipeline::sUnderWaterRender) + { + mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]); + } + mShader->bind(); diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP); @@ -215,3 +221,4 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, gGL.matrixMode(LLRender::MM_MODELVIEW); } } + diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 2cf9d833c6..8926f64c64 100755 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -37,6 +37,7 @@ #include "llviewershadermgr.h" #include "llrender.h" +#define GE_FORCE_WORKAROUND LL_DARWIN static LLGLSLShader* simple_shader = NULL; static LLGLSLShader* fullbright_shader = NULL; @@ -111,7 +112,14 @@ void LLDrawPoolGlow::render(S32 pass) LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; shader->bind(); - shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f); + if (LLPipeline::sRenderDeferred) + { + shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + } + else + { + shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f); + } LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.setColorMask(false, true); @@ -148,7 +156,11 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass) { LLFastTimer t(FTM_RENDER_SIMPLE); - if (LLPipeline::sUnderWaterRender) + if (LLPipeline::sImpostorRender) + { + simple_shader = &gObjectSimpleImpostorProgram; + } + else if (LLPipeline::sUnderWaterRender) { simple_shader = &gObjectSimpleWaterProgram; } @@ -536,7 +548,15 @@ void LLDrawPoolFullbright::prerender() void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) { - gDeferredFullbrightProgram.bind(); + if (LLPipeline::sUnderWaterRender) + { + gDeferredFullbrightWaterProgram.bind(); + } + else + { + gDeferredFullbrightProgram.bind(); + } + } void LLDrawPoolFullbright::renderPostDeferred(S32 pass) @@ -550,7 +570,14 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass) void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) { - gDeferredFullbrightProgram.unbind(); + if (LLPipeline::sUnderWaterRender) + { + gDeferredFullbrightWaterProgram.unbind(); + } + else + { + gDeferredFullbrightProgram.unbind(); + } LLRenderPass::endRenderPass(pass); } @@ -625,15 +652,35 @@ S32 LLDrawPoolFullbright::getNumPasses() void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass) { - gObjectFullbrightAlphaMaskProgram.bind(); + if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) { + gObjectFullbrightAlphaMaskProgram.bind(); gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); } else - { + { + +// Work-around until we can figure out why the right shader causes +// the GeForce driver to go tango uniform on OS X 10.6.8 only +// +#if GE_FORCE_WORKAROUND + gObjectFullbrightAlphaMaskProgram.bind(); gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +#else + if (LLPipeline::sUnderWaterRender) + { + gDeferredFullbrightAlphaMaskWaterProgram.bind(); + gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + } + else + { + gDeferredFullbrightAlphaMaskProgram.bind(); + gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + } +#endif } + } void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass) @@ -646,7 +693,30 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass) void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass) { - gObjectFullbrightAlphaMaskProgram.unbind(); + if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) + { + gObjectFullbrightAlphaMaskProgram.unbind(); + } + else + { + +// Work-around until we can figure out why the right shader causes +// the GeForce driver to go tango uniform on OS X 10.6.8 only +// +#if GE_FORCE_WORKAROUND + gObjectFullbrightAlphaMaskProgram.unbind(); +#else + if (LLPipeline::sUnderWaterRender) + { + gDeferredFullbrightAlphaMaskWaterProgram.unbind(); + } + else + { + gDeferredFullbrightAlphaMaskProgram.unbind(); + } +#endif + + } LLRenderPass::endRenderPass(pass); } diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index 7f7d9f65c6..ef8bdc3304 100755 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -155,3 +155,4 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side) void LLDrawPoolSky::endRenderPass( S32 pass ) { } + diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 5ddc15df42..6774926f62 100755 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -522,13 +522,20 @@ void LLDrawPoolWater::shade() F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); - if (deferred_render) + if (eyedepth < 0.f && LLPipeline::sWaterReflections) { - shader = &gDeferredWaterProgram; + if (deferred_render) + { + shader = &gDeferredUnderWaterProgram; + } + else + { + shader = &gUnderWaterProgram; + } } - else if (eyedepth < 0.f && LLPipeline::sWaterReflections) + else if (deferred_render) { - shader = &gUnderWaterProgram; + shader = &gDeferredWaterProgram; } else { diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index b5faff7968..53339222eb 100755 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -420,3 +420,4 @@ void LLDrawPoolWLSky::restoreGL() sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE); } } + diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 9b2b778677..53e5b55b89 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -821,21 +821,21 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, { v[i].setSelectWithMask(mask[i], min, max); } - + LLVector4a tv[8]; - + //transform bounding box into drawable space for (U32 i = 0; i < 8; ++i) { mat_vert.affineTransform(v[i], tv[i]); } - + //find bounding box LLVector4a& newMin = mExtents[0]; LLVector4a& newMax = mExtents[1]; - + newMin = newMax = tv[0]; - + for (U32 i = 1; i < 8; ++i) { newMin.setMin(newMin, tv[i]); @@ -851,11 +851,11 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, } LLVector4a t; - t.setAdd(newMin,newMax); + t.setAdd(newMin, newMax); t.mul(0.5f); mCenterLocal.set(t.getF32ptr()); - + t.setSub(newMax,newMin); mBoundingSphereRadius = t.getLength3().getF32()*0.5f; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 763634a3ab..66b5f13740 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -194,8 +194,7 @@ public: void setSize(S32 numVertices, S32 num_indices = 0, bool align = false); - BOOL genVolumeBBoxes(const LLVolume &volume, S32 f, - const LLMatrix4& mat, BOOL global_volume = FALSE); + BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,const LLMatrix4& mat, BOOL global_volume = FALSE); void init(LLDrawable* drawablep, LLViewerObject* objp); void destroy(); diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index d13f85baa2..b26d520557 100755 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -62,6 +62,11 @@ LLFilePicker LLFilePicker::sInstance; #define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" #endif +#ifdef LL_DARWIN +#include "llfilepicker_mac.h" +//#include <boost/algorithm/string/predicate.hpp> +#endif + // // Implementation // @@ -94,14 +99,6 @@ LLFilePicker::LLFilePicker() mFilesW[0] = '\0'; #endif -#if LL_DARWIN - memset(&mNavOptions, 0, sizeof(mNavOptions)); - OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions); - if (error == noErr) - { - mNavOptions.modality = kWindowModalityAppModal; - } -#endif } LLFilePicker::~LLFilePicker() @@ -546,369 +543,197 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) #elif LL_DARWIN -Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) +std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) { - Boolean result = true; - ELoadFilter filter = *((ELoadFilter*) callBackUD); - OSStatus error = noErr; - - if (filterMode == kNavFilteringBrowserList && filter != FFLOAD_ALL && (theItem->descriptorType == typeFSRef || theItem->descriptorType == typeFSS)) - { - // navInfo is only valid for typeFSRef and typeFSS - NavFileOrFolderInfo *navInfo = (NavFileOrFolderInfo*) info; - if (!navInfo->isFolder) - { - AEDesc desc; - error = AECoerceDesc(theItem, typeFSRef, &desc); - if (error == noErr) - { - FSRef fileRef; - error = AEGetDescData(&desc, &fileRef, sizeof(fileRef)); - if (error == noErr) - { - LSItemInfoRecord fileInfo; - error = LSCopyItemInfoForRef(&fileRef, kLSRequestExtension | kLSRequestTypeCreator, &fileInfo); - if (error == noErr) - { - if (filter == FFLOAD_IMAGE) - { - if (fileInfo.filetype != 'JPEG' && fileInfo.filetype != 'JPG ' && - fileInfo.filetype != 'BMP ' && fileInfo.filetype != 'TGA ' && - fileInfo.filetype != 'BMPf' && fileInfo.filetype != 'TPIC' && - fileInfo.filetype != 'PNG ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("jpeg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("jpg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("bmp"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("tga"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("png"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_WAV) - { - if (fileInfo.filetype != 'WAVE' && fileInfo.filetype != 'WAV ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("wave"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("wav"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_ANIM) - { - if (fileInfo.filetype != 'BVH ' && - fileInfo.filetype != 'ANIM' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && - fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("anim"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_COLLADA) - { - if (fileInfo.filetype != 'DAE ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dae"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } + std::vector<std::string> *allowedv = new std::vector< std::string >; + switch(filter) + { + case FFLOAD_ALL: + allowedv->push_back("wav"); + allowedv->push_back("bvh"); + allowedv->push_back("anim"); + allowedv->push_back("dae"); + allowedv->push_back("raw"); + allowedv->push_back("lsl"); + allowedv->push_back("dic"); + allowedv->push_back("xcu"); + case FFLOAD_IMAGE: + allowedv->push_back("jpg"); + allowedv->push_back("jpeg"); + allowedv->push_back("bmp"); + allowedv->push_back("tga"); + allowedv->push_back("bmpf"); + allowedv->push_back("tpic"); + allowedv->push_back("png"); + break; + case FFLOAD_WAV: + allowedv->push_back("wav"); + break; + case FFLOAD_ANIM: + allowedv->push_back("bvh"); + allowedv->push_back("anim"); + break; + case FFLOAD_COLLADA: + allowedv->push_back("dae"); + break; #ifdef _CORY_TESTING - else if (filter == FFLOAD_GEOMETRY) - { - if (fileInfo.filetype != 'SLG ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("slg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } + case FFLOAD_GEOMETRY: + allowedv->push_back("slg"); + break; #endif - else if (filter == FFLOAD_SLOBJECT) - { - llwarns << "*** navOpenFilterProc: FFLOAD_SLOBJECT NOT IMPLEMENTED ***" << llendl; - } - else if (filter == FFLOAD_RAW) - { - if (fileInfo.filetype != '\?\?\?\?' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("raw"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_SCRIPT) - { - if (fileInfo.filetype != 'LSL ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("lsl"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) - { - result = false; - } - } - else if (filter == FFLOAD_DICTIONARY) - { - if (fileInfo.filetype != 'DIC ' && - fileInfo.filetype != 'XCU ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dic"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && - fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xcu"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))) - { - result = false; - } - } - - if (fileInfo.extension) - { - CFRelease(fileInfo.extension); - } - } - } - AEDisposeDesc(&desc); - } - } - } - return result; + case FFLOAD_RAW: + allowedv->push_back("raw"); + break; + case FFLOAD_SCRIPT: + allowedv->push_back("lsl"); + break; + case FFLOAD_DICTIONARY: + allowedv->push_back("dic"); + allowedv->push_back("xcu"); + break; + case FFLOAD_DIRECTORY: + break; + default: + llwarns << "Unsupported format." << llendl; + } + + return allowedv; } -OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter) +bool LLFilePicker::doNavChooseDialog(ELoadFilter filter) { - OSStatus error = noErr; - NavDialogRef navRef = NULL; - NavReplyRecord navReply; - // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { - return FALSE; + return false; } - - memset(&navReply, 0, sizeof(navReply)); - - // NOTE: we are passing the address of a local variable here. - // This is fine, because the object this call creates will exist for less than the lifetime of this function. - // (It is destroyed by NavDialogDispose() below.) - error = NavCreateChooseFileDialog(&mNavOptions, NULL, NULL, NULL, navOpenFilterProc, (void*)(&filter), &navRef); - + gViewerWindow->getWindow()->beforeDialog(); - - if (error == noErr) - error = NavDialogRun(navRef); + + std::vector<std::string> *allowed_types=navOpenFilterProc(filter); + + std::vector<std::string> *filev = doLoadDialog(allowed_types, + mPickOptions); gViewerWindow->getWindow()->afterDialog(); - if (error == noErr) - error = NavDialogGetReply(navRef, &navReply); - if (navRef) - NavDialogDispose(navRef); - - if (error == noErr && navReply.validRecord) - { - SInt32 count = 0; - SInt32 index; - - // AE indexes are 1 based... - error = AECountItems(&navReply.selection, &count); - for (index = 1; index <= count; index++) - { - FSRef fsRef; - AEKeyword theAEKeyword; - DescType typeCode; - Size actualSize = 0; - char path[MAX_PATH]; /*Flawfinder: ignore*/ - - memset(&fsRef, 0, sizeof(fsRef)); - error = AEGetNthPtr(&navReply.selection, index, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); - - if (error == noErr) - error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path)); - - if (error == noErr) - mFiles.push_back(std::string(path)); - } - } + if (filev && filev->size() > 0) + { + mFiles.insert(mFiles.end(), filev->begin(), filev->end()); + return true; + } - return error; + return false; } -OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename) +bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename) { - OSStatus error = noErr; - NavDialogRef navRef = NULL; - NavReplyRecord navReply; - - memset(&navReply, 0, sizeof(navReply)); // Setup the type, creator, and extension - OSType type, creator; - CFStringRef extension = NULL; + std::string extension, type, creator; + switch (filter) { case FFSAVE_WAV: - type = 'WAVE'; - creator = 'TVOD'; - extension = CFSTR(".wav"); + type = "WAVE"; + creator = "TVOD"; + extension = "wav"; break; case FFSAVE_TGA: - type = 'TPIC'; - creator = 'prvw'; - extension = CFSTR(".tga"); + type = "TPIC"; + creator = "prvw"; + extension = "tga"; break; case FFSAVE_BMP: - type = 'BMPf'; - creator = 'prvw'; - extension = CFSTR(".bmp"); + type = "BMPf"; + creator = "prvw"; + extension = "bmp"; break; case FFSAVE_JPEG: - type = 'JPEG'; - creator = 'prvw'; - extension = CFSTR(".jpeg"); + type = "JPEG"; + creator = "prvw"; + extension = "jpeg"; break; case FFSAVE_PNG: - type = 'PNG '; - creator = 'prvw'; - extension = CFSTR(".png"); + type = "PNG "; + creator = "prvw"; + extension = "png"; break; case FFSAVE_AVI: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".mov"); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "mov"; break; case FFSAVE_ANIM: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".xaf"); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "xaf"; break; #ifdef _CORY_TESTING case FFSAVE_GEOMETRY: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".slg"); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "slg"; break; #endif case FFSAVE_RAW: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".raw"); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = "raw"; break; case FFSAVE_J2C: - type = '\?\?\?\?'; - creator = 'prvw'; - extension = CFSTR(".j2c"); + type = "\?\?\?\?"; + creator = "prvw"; + extension = "j2c"; break; case FFSAVE_SCRIPT: - type = 'LSL '; - creator = '\?\?\?\?'; - extension = CFSTR(".lsl"); + type = "LSL "; + creator = "\?\?\?\?"; + extension = "lsl"; break; case FFSAVE_ALL: default: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(""); + type = "\?\?\?\?"; + creator = "\?\?\?\?"; + extension = ""; break; } - // Create the dialog - error = NavCreatePutFileDialog(&mNavOptions, type, creator, NULL, NULL, &navRef); - if (error == noErr) - { - CFStringRef nameString = NULL; - bool hasExtension = true; - - // Create a CFString of the initial file name - if (!filename.empty()) - nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8); - else - nameString = CFSTR("Untitled"); - - // Add the extension if one was not provided - if (nameString && !CFStringHasSuffix(nameString, extension)) - { - CFStringRef tempString = nameString; - hasExtension = false; - nameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), tempString, extension); - CFRelease(tempString); - } - - // Set the name in the dialog - if (nameString) - { - error = NavDialogSetSaveFileName(navRef, nameString); - CFRelease(nameString); - } - else - { - error = paramErr; - } - } - + std::string namestring = filename; + if (namestring.empty()) namestring="Untitled"; + +// if (! boost::algorithm::ends_with(namestring, extension) ) +// { +// namestring = namestring + "." + extension; +// +// } + gViewerWindow->getWindow()->beforeDialog(); // Run the dialog - if (error == noErr) - error = NavDialogRun(navRef); + std::string* filev = doSaveDialog(&namestring, + &type, + &creator, + &extension, + mPickOptions); gViewerWindow->getWindow()->afterDialog(); - if (error == noErr) - error = NavDialogGetReply(navRef, &navReply); - - if (navRef) - NavDialogDispose(navRef); - - if (error == noErr && navReply.validRecord) + if ( filev && !filev->empty() ) { - SInt32 count = 0; - - // AE indexes are 1 based... - error = AECountItems(&navReply.selection, &count); - if (count > 0) - { - // Get the FSRef to the containing folder - FSRef fsRef; - AEKeyword theAEKeyword; - DescType typeCode; - Size actualSize = 0; - - memset(&fsRef, 0, sizeof(fsRef)); - error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); - - if (error == noErr) - { - char path[PATH_MAX]; /*Flawfinder: ignore*/ - char newFileName[SINGLE_FILENAME_BUFFER_SIZE]; /*Flawfinder: ignore*/ - - error = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX); - if (error == noErr) - { - if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8)) - { - mFiles.push_back(std::string(path) + "/" + std::string(newFileName)); - } - else - { - error = paramErr; - } - } - else - { - error = paramErr; - } - } - } - } + mFiles.push_back(*filev); + return true; + } - return error; + return false; } BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) @@ -924,16 +749,21 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) return FALSE; } - OSStatus error = noErr; - reset(); - mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; + mPickOptions &= ~F_MULTIPLE; + mPickOptions |= F_FILE; + + if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker. + { + + mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY ); + mPickOptions &= ~F_FILE; + } if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful { - // mNavOptions.optionFlags |= kNavAllowOpenPackages; - mNavOptions.optionFlags |= kNavSupportPackages; + mPickOptions &= F_NAV_SUPPORT; } if (blocking) @@ -942,14 +772,13 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) send_agent_pause(); } + + success = doNavChooseDialog(filter); + + if (success) { - error = doNavChooseDialog(filter); - } - - if (error == noErr) - { - if (getFileCount()) - success = true; + if (!getFileCount()) + success = false; } if (blocking) @@ -975,21 +804,22 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) return FALSE; } - OSStatus error = noErr; - reset(); - - mNavOptions.optionFlags |= kNavAllowMultipleFiles; + + mPickOptions |= F_FILE; + + mPickOptions |= F_MULTIPLE; // Modal, so pause agent send_agent_pause(); + + success = doNavChooseDialog(filter); + + send_agent_resume(); + + if (success) { - error = doNavChooseDialog(filter); - } - send_agent_resume(); - if (error == noErr) - { - if (getFileCount()) - success = true; + if (!getFileCount()) + success = false; if (getFileCount() > 1) mLocked = true; } @@ -1001,37 +831,37 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) { + if( mLocked ) - return FALSE; - BOOL success = FALSE; - OSStatus error = noErr; + return false; + BOOL success = false; // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { - return FALSE; + return false; } reset(); - mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; + mPickOptions &= ~F_MULTIPLE; // Modal, so pause agent send_agent_pause(); + + success = doNavSaveDialog(filter, filename); + + if (success) { - error = doNavSaveDialog(filter, filename); - } - send_agent_resume(); - if (error == noErr) - { - if (getFileCount()) - success = true; + if (!getFileCount()) + success = false; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; } +//END LL_DARWIN #elif LL_LINUX || LL_SOLARIS @@ -1537,4 +1367,4 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter ) return FALSE; } -#endif +#endif // LL_LINUX || LL_SOLARIS diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 4f602f63f1..0d279f73f3 100755 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -39,8 +39,8 @@ #include <Carbon/Carbon.h> // AssertMacros.h does bad things. -#include "fix_macros.h" #undef verify +#undef check #undef require #include <vector> @@ -85,7 +85,8 @@ public: FFLOAD_MODEL = 9, FFLOAD_COLLADA = 10, FFLOAD_SCRIPT = 11, - FFLOAD_DICTIONARY = 12 + FFLOAD_DICTIONARY = 12, + FFLOAD_DIRECTORY = 13 //To call from lldirpicker. }; enum ESaveFilter @@ -158,15 +159,14 @@ private: #endif #if LL_DARWIN - NavDialogCreationOptions mNavOptions; + S32 mPickOptions; std::vector<std::string> mFileVector; UInt32 mFileIndex; - OSStatus doNavChooseDialog(ELoadFilter filter); - OSStatus doNavSaveDialog(ESaveFilter filter, const std::string& filename); - void getFilePath(SInt32 index); - void getFileName(SInt32 index); - static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode); + bool doNavChooseDialog(ELoadFilter filter); + bool doNavSaveDialog(ESaveFilter filter, const std::string& filename); + //static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode); + std::vector<std::string>* navOpenFilterProc(ELoadFilter filter); #endif #if LL_GTK diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h new file mode 100644 index 0000000000..e0b7e2e8ce --- /dev/null +++ b/indra/newview/llfilepicker_mac.h @@ -0,0 +1,58 @@ +/** + * @file llfilepicker_mac.h + * @brief OS-specific file picker + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// OS specific file selection dialog. This is implemented as a +// singleton class, so call the instance() method to get the working +// instance. When you call getMultipleOpenFile(), it locks the picker +// until you iterate to the end of the list of selected files with +// getNextFile() or call reset(). + +#ifndef LL_LLFILEPICKER_MAC_H +#define LL_LLFILEPICKER_MAC_H + +#if LL_DARWIN + +#include <string> +#include <vector> + +//void modelessPicker(); +std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, + unsigned int flags); +std::string* doSaveDialog(const std::string* file, + const std::string* type, + const std::string* creator, + const std::string* extension, + unsigned int flags); +enum { + F_FILE = 0x00000001, + F_DIRECTORY = 0x00000002, + F_MULTIPLE = 0x00000004, + F_NAV_SUPPORT=0x00000008 +}; + +#endif + +#endif diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm new file mode 100644 index 0000000000..2a84226e0a --- /dev/null +++ b/indra/newview/llfilepicker_mac.mm @@ -0,0 +1,132 @@ +/** + * @file llfilepicker_mac.cpp + * @brief OS-specific file picker + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifdef LL_DARWIN +#import <Cocoa/Cocoa.h> +#include <iostream> +#include "llfilepicker_mac.h" + +std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, + unsigned int flags) +{ + int i, result; + + //Aura TODO: We could init a small window and release it at the end of this routine + //for a modeless interface. + + NSOpenPanel *panel = [NSOpenPanel openPanel]; + //NSString *fileName = nil; + NSMutableArray *fileTypes = nil; + + + if ( allowed_types && !allowed_types->empty()) + { + fileTypes = [[NSMutableArray alloc] init]; + + for (i=0;i<allowed_types->size();++i) + { + [fileTypes addObject: + [NSString stringWithCString:(*allowed_types)[i].c_str() + encoding:[NSString defaultCStringEncoding]]]; + } + } + + //[panel setMessage:@"Import one or more files or directories."]; + [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ]; + [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ]; + [panel setCanCreateDirectories: true]; + [panel setResolvesAliases: true]; + [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; + + std::vector<std::string>* outfiles = NULL; + + if (fileTypes) + { + [panel setAllowedFileTypes:fileTypes]; + result = [panel runModal]; + } + else + { + // I suggest it's better to open the last path and let this default to home dir as necessary + // for consistency with other OS X apps + // + //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ]; + result = [panel runModal]; + } + + if (result == NSOKButton) + { + NSArray *filesToOpen = [panel URLs]; + int i, count = [filesToOpen count]; + + if (count > 0) + { + outfiles = new std::vector<std::string>; + } + + for (i=0; i<count; i++) { + NSString *aFile = [[filesToOpen objectAtIndex:i] path]; + std::string *afilestr = new std::string([aFile UTF8String]); + outfiles->push_back(*afilestr); + } + } + return outfiles; +} + + +std::string* doSaveDialog(const std::string* file, + const std::string* type, + const std::string* creator, + const std::string* extension, + unsigned int flags) +{ + NSSavePanel *panel = [NSSavePanel savePanel]; + + NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; + NSArray *fileType = [[NSArray alloc] initWithObjects:extensionns,nil]; + + //[panel setMessage:@"Save Image File"]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; + [panel setCanSelectHiddenExtension:true]; + [panel setAllowedFileTypes:fileType]; + NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; + + std::string *outfile = NULL; + NSURL* url = [NSURL fileURLWithPath:fileName]; + [panel setDirectoryURL: url]; + if([panel runModal] == + NSFileHandlingPanelOKButton) + { + NSURL* url = [panel URL]; + NSString* p = [url path]; + outfile = new std::string( [p UTF8String] ); + // write the file + } + return outfile; +} + +#endif diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 116bd241c4..792a2a5d25 100755 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -89,8 +89,10 @@ void LLFloaterHardwareSettings::refresh() void LLFloaterHardwareSettings::refreshEnabledState() { + F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); + S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); - S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(); + S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier); getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem); getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem); @@ -149,12 +151,17 @@ BOOL LLFloaterHardwareSettings::postBuild() { childSetAction("OK", onBtnOK, this); +// Don't do this on Mac as their braindead GL versioning +// sets this when 8x and 16x are indeed available +// +#if !LL_DARWIN if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f) { //remove FSAA settings above "4x" LLComboBox* combo = getChild<LLComboBox>("fsaa"); combo->remove("8x"); combo->remove("16x"); } +#endif refresh(); center(); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 14923eec3c..7b25291da7 100755 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -1328,7 +1328,7 @@ void LLFloaterTools::getMediaState() getChildView("media_tex")->setEnabled(bool_has_media && editable); getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable ); getChildView("delete_media")->setEnabled(bool_has_media && editable ); - getChildView("add_media")->setEnabled(( ! bool_has_media ) && editable ); + getChildView("add_media")->setEnabled(editable); // TODO: display a list of all media on the face - use 'identical' flag } else // not all face has media but at least one does. @@ -1358,7 +1358,7 @@ void LLFloaterTools::getMediaState() getChildView("media_tex")->setEnabled(TRUE); getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo); getChildView("delete_media")->setEnabled(TRUE); - getChildView("add_media")->setEnabled(FALSE ); + getChildView("add_media")->setEnabled(editable); } media_info->setText(media_title); diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index ecb0092a6f..189bae46c2 100755 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -109,6 +109,8 @@ public: static void setGridMode(S32 mode); + LLPanelFace* getPanelFace() { return mPanelFace; } + private: void refresh(); void refreshMedia(); diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 16871adc4d..658fea944d 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -51,12 +51,9 @@ #define MATERIALS_CAP_OBJECT_ID_FIELD "ID" #define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID" -#define MATERIALS_GET_MAX_ENTRIES 50 #define MATERIALS_GET_TIMEOUT (60.f * 20) -#define MATERIALS_POST_MAX_ENTRIES 50 #define MATERIALS_POST_TIMEOUT (60.f * 5) #define MATERIALS_PUT_THROTTLE_SECS 1.f -#define MATERIALS_PUT_MAX_ENTRIES 50 /** * LLMaterialsResponder helper class @@ -544,11 +541,9 @@ void LLMaterialMgr::onIdle(void*) instancep->processGetAllQueue(); } - static LLFrameTimer mPutTimer; - if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) ) + if (!instancep->mPutQueue.empty()) { instancep->processPutQueue(); - mPutTimer.resetWithExpiry(MATERIALS_PUT_THROTTLE_SECS); } } @@ -565,14 +560,14 @@ void LLMaterialMgr::processGetQueue() continue; } - const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); + LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); if (!regionp) { LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL; mGetQueue.erase(itRegionQueue); continue; } - else if (!regionp->capabilitiesReceived()) + else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled()) { continue; } @@ -595,8 +590,9 @@ void LLMaterialMgr::processGetQueue() LLSD materialsData = LLSD::emptyArray(); material_queue_t& materials = itRegionQueue->second; - material_queue_t::iterator loopMaterial = materials.begin(); - while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) ) + U32 max_entries = regionp->getMaxMaterialsPerTransaction(); + material_queue_t::iterator loopMaterial = materials.begin(); + while ( (materials.end() != loopMaterial) && (materialsData.size() < max_entries) ) { material_queue_t::iterator itMaterial = loopMaterial++; materialsData.append((*itMaterial).asLLSD()); @@ -628,6 +624,7 @@ void LLMaterialMgr::processGetQueue() LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials." << "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL; LLHTTPClient::post(capURL, postData, materialsResponder); + regionp->resetMaterialsCapThrottle(); } } @@ -646,7 +643,7 @@ void LLMaterialMgr::processGetAllQueue() clearGetQueues(region_id); // Invalidates region_id continue; } - else if (!regionp->capabilitiesReceived()) + else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled()) { continue; } @@ -663,6 +660,7 @@ void LLMaterialMgr::processGetAllQueue() LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL; LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion)); LLHTTPClient::get(capURL, materialsResponder); + regionp->resetMaterialsCapThrottle(); mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds())); mGetAllQueue.erase(itRegion); // Invalidates region_id } @@ -670,7 +668,7 @@ void LLMaterialMgr::processGetAllQueue() void LLMaterialMgr::processPutQueue() { - typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map; + typedef std::map<LLViewerRegion*, LLSD> regionput_request_map; regionput_request_map requests; put_queue_t::iterator loopQueue = mPutQueue.begin(); @@ -680,49 +678,54 @@ void LLMaterialMgr::processPutQueue() const LLUUID& object_id = itQueue->first; const LLViewerObject* objectp = gObjectList.findObject(object_id); - if ( (!objectp) || (!objectp->getRegion()) ) + if ( !objectp ) { - LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL; - + LL_WARNS("Materials") << "Object is NULL" << LL_ENDL; mPutQueue.erase(itQueue); - continue; } - - const LLViewerRegion* regionp = objectp->getRegion(); - if (!regionp->capabilitiesReceived()) - { - continue; - } - - LLSD& facesData = requests[regionp]; - - facematerial_map_t& face_map = itQueue->second; - facematerial_map_t::iterator itFace = face_map.begin(); - while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) ) + else { - LLSD faceData = LLSD::emptyMap(); - faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first); - faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID()); - if (!itFace->second.isNull()) + LLViewerRegion* regionp = objectp->getRegion(); + if ( !regionp ) { - faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD(); + LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL; + mPutQueue.erase(itQueue); + } + else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled()) + { + LLSD& facesData = requests[regionp]; + + facematerial_map_t& face_map = itQueue->second; + U32 max_entries = regionp->getMaxMaterialsPerTransaction(); + facematerial_map_t::iterator itFace = face_map.begin(); + while ( (face_map.end() != itFace) && (facesData.size() < max_entries) ) + { + LLSD faceData = LLSD::emptyMap(); + faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first); + faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID()); + if (!itFace->second.isNull()) + { + faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD(); + } + facesData.append(faceData); + face_map.erase(itFace++); + } + if (face_map.empty()) + { + mPutQueue.erase(itQueue); + } } - facesData.append(faceData); - face_map.erase(itFace++); - } - if (face_map.empty()) - { - mPutQueue.erase(itQueue); } } for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest) { - std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME); + LLViewerRegion* regionp = itRequest->first; + std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); if (capURL.empty()) { LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME - << "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL; + << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL; continue; } @@ -745,6 +748,7 @@ void LLMaterialMgr::processPutQueue() LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL; LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)); LLHTTPClient::put(capURL, putData, materialsResponder); + regionp->resetMaterialsCapThrottle(); } else { @@ -773,7 +777,6 @@ void LLMaterialMgr::clearGetQueues(const LLUUID& region_id) mGetAllPending.erase(region_id); mGetAllCallbacks.erase(region_id); } - void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp) { clearGetQueues(regionp->getRegionID()); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 911af9df04..3869219da6 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -66,7 +66,7 @@ #include "llvovolume.h" #include "lluictrlfactory.h" #include "llpluginclassmedia.h" -#include "llviewertexturelist.h" +#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI // // Constant definitions for comboboxes @@ -89,6 +89,19 @@ const S32 SHINY_TEXTURE = 4; // use supplied specular map // std::string USE_TEXTURE; +LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit() +{ + LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); + LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype"); + + LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? + (combobox_mattype ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP; + + channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; + channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; + return channel_to_edit; +} + // Things the UI provides... // LLUUID LLPanelFace::getCurrentNormalMap() { return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); } @@ -1194,7 +1207,8 @@ void LLPanelFace::updateUI() getChildView("checkbox fullbright")->setEnabled(editable); getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright); } - + + // Repeats per meter { F32 repeats_diff = 1.f; @@ -1218,6 +1232,9 @@ void LLPanelFace::updateUI() F32 repeats = 1.0f; U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE; + + LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type)); + switch (material_type) { default: @@ -1328,18 +1345,6 @@ void LLPanelFace::updateUI() getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE); } - // Update sel manager as to which channel we're editing so it can reflect the correct overlay UI - // NORSPEC-103 - LLRender::eTexIndex channel_to_edit = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP; - - if ( ((channel_to_edit == LLRender::NORMAL_MAP) && material->getNormalID().isNull()) - ||((channel_to_edit == LLRender::SPECULAR_MAP) && material->getSpecularID().isNull())) - { - channel_to_edit = LLRender::DIFFUSE_MAP; - } - - LLSelectMgr::getInstance()->setTextureChannel(channel_to_edit); - // Bumpy (normal) texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); texture_ctrl->setImageAssetID(material->getNormalID()); @@ -1365,10 +1370,6 @@ void LLPanelFace::updateUI() updateBumpyControls(!material->getNormalID().isNull(), true); } } - else - { - LLSelectMgr::getInstance()->setTextureChannel(LLRender::DIFFUSE_MAP); - } } // Set variable values for numeric expressions diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 42c1f6bd48..46b3375f64 100755 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -100,6 +100,19 @@ public: void setMediaURL(const std::string& url); void setMediaType(const std::string& mime_type); + LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) + { + LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); + llassert_always(new_material); + + // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture + // + new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); + return new_material; + } + + LLRender::eTexIndex getTextureChannelToEdit(); + protected: void getState(); @@ -178,6 +191,8 @@ protected: static F32 valueGlow(LLViewerObject* object, S32 face); + + private: bool isAlpha() { return mIsAlpha; } @@ -234,17 +249,32 @@ private: { if (_edit) { - LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); + LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); llassert_always(new_material); // Determine correct alpha mode for current diffuse texture // (i.e. does it have an alpha channel that makes alpha mode useful) // - U8 default_alpha_mode = (_panel->isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) + // need to get per-face answer to this question for sane alpha mode retention on updates. + // + bool is_alpha_face = object->isImageAlphaBlended(face); + + // need to keep this original answer for valid comparisons in logic below + // + U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + U8 default_alpha_mode = original_default_alpha_mode; + + if (!current_material.isNull()) + { + default_alpha_mode = current_material->getDiffuseAlphaMode(); + } - // Default to matching expected state of UI + // Insure we don't inherit the default of blend by accident... + // this will be stomped by a legit request to change the alpha mode by the apply() below // - new_material->setDiffuseAlphaMode(current_material.isNull() ? default_alpha_mode : current_material->getDiffuseAlphaMode()); + new_material->setDiffuseAlphaMode(default_alpha_mode); // Do "It"! // @@ -254,7 +284,13 @@ private: LLUUID new_normal_map_id = new_material->getNormalID(); LLUUID new_spec_map_id = new_material->getSpecularID(); - bool is_default_blend_mode = (new_alpha_mode == default_alpha_mode); + if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) + { + new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + } + + bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); if (!is_need_material) diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 02d363d795..a1d60b5b16 100755 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -710,9 +710,19 @@ void LLPanelVolume::onLightCancelColor(const LLSD& data) void LLPanelVolume::onLightCancelTexture(const LLSD& data) { LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control"); + if (LightTextureCtrl) { - LightTextureCtrl->setImageAssetID(mLightSavedTexture); + LightTextureCtrl->setImageAssetID(LLUUID::null); + } + + LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); + if(volobjp) + { + // Cancel the light texture as requested + // NORSPEC-292 + // + volobjp->setLightTextureID(LLUUID::null); } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 0cbdbe16a3..7b397d46f3 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -91,7 +91,7 @@ #include "llvovolume.h" #include "pipeline.h" #include "llviewershadermgr.h" - +#include "llpanelface.h" #include "llglheaders.h" LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; @@ -2534,7 +2534,7 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) if (tep && !tep->getMaterialParams().isNull()) { LLMaterialPtr orig = tep->getMaterialParams(); - LLMaterialPtr p = new LLMaterial(orig->asLLSD()); + LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); p->setNormalRepeat(normal_scale_s, normal_scale_t); p->setSpecularRepeat(specular_scale_s, specular_scale_t); @@ -2560,8 +2560,8 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) if (tep && !tep->getMaterialParams().isNull()) { LLMaterialPtr orig = tep->getMaterialParams(); + LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); - LLMaterialPtr p = new LLMaterial(orig->asLLSD()); p->setNormalRepeat(normal_scale_s, normal_scale_t); p->setSpecularRepeat(specular_scale_s, specular_scale_t); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 4676f7b251..2b1ed5858a 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -133,7 +133,8 @@ public: PermissionMask getFilterPermMask(); void updateFilterPermMask(); void commitIfImmediateSet(); - + void commitCancel(); + void onFilterEdit(const std::string& search_string ); void setCanApply(bool can_preview, bool can_apply); @@ -706,6 +707,14 @@ void LLFloaterTexturePicker::commitIfImmediateSet() } } +void LLFloaterTexturePicker::commitCancel() +{ + if (!mNoCopyTextureSelected && mOwner && mCanApply) + { + mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL); + } +} + // static void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata) { @@ -733,7 +742,7 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; self->setImageID( LLUUID::null ); - self->commitIfImmediateSet(); + self->commitCancel(); } /* diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index e085834326..ef7d0cd81b 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -58,6 +58,7 @@ #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llworld.h" +#include "llpanelface.h" // syntactic sugar #define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember)) @@ -1163,7 +1164,51 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, // update viewer side image in anticipation of update from simulator LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); - hit_obj->setTEImage(hit_face, image); + + LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL; + + LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + + if (gFloaterTools->getVisible() && panel_face) + { + switch (LLSelectMgr::getInstance()->getTextureChannel()) + { + + case 0: + default: + { + hit_obj->setTEImage(hit_face, image); + } + break; + + case 1: + { + LLMaterialPtr old_mat = tep->getMaterialParams(); + LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); + new_mat->setNormalID(asset_id); + tep->setMaterialParams(new_mat); + hit_obj->setTENormalMap(hit_face, asset_id); + LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); + } + break; + + case 2: + { + LLMaterialPtr old_mat = tep->getMaterialParams(); + LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); + new_mat->setSpecularID(asset_id); + tep->setMaterialParams(new_mat); + hit_obj->setTESpecularMap(hit_face, asset_id); + LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); + } + break; + } + } + else + { + hit_obj->setTEImage(hit_face, image); + } + dialog_refresh_all(); // send the update to the simulator diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index f90b35a7bd..bbebeea3e0 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -890,7 +890,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { gGL.setColorMask(true, true); - if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) + if (LLPipeline::sRenderDeferred) { gPipeline.mDeferredScreen.bindTarget(); glClearColor(1,0,1,1); @@ -939,7 +939,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gGL.setColorMask(true, false); - if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) + if (LLPipeline::sRenderDeferred) { gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance()); } @@ -976,7 +976,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (to_texture) { - if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) + if (LLPipeline::sRenderDeferred) { gPipeline.mDeferredScreen.flush(); if(LLRenderTarget::sUseFBO) @@ -1002,7 +1002,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } } - if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) + if (LLPipeline::sRenderDeferred) { gPipeline.renderDeferredLighting(); } @@ -1623,3 +1623,4 @@ void display_cleanup() { gDisconnectedImagep = NULL; } + diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 4ecdc31e21..47a8a04b63 100755 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -676,6 +676,7 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) { mKeyHandledByUI[translated_key] = FALSE; + LL_INFOS("Keyboard Handling") << "Key wasn't handled by UI!" << LL_ENDL; } else { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6f7b2f40e6..0070240803 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4410,12 +4410,10 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri void LLViewerObject::refreshMaterials() { - setChanged(ALL_CHANGED); + setChanged(TEXTURE); if (mDrawable.notNull()) { gPipeline.markTextured(mDrawable); - gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); - dirtySpatialGroup(TRUE); } } @@ -4519,6 +4517,30 @@ LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const } +bool LLViewerObject::isImageAlphaBlended(const U8 te) const +{ + LLViewerTexture* image = getTEImage(te); + LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB; + switch (format) + { + case GL_RGBA: + case GL_ALPHA: + { + return true; + } + break; + + case GL_RGB: break; + default: + { + llwarns << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << llendl; + } + break; + } + + return false; +} + LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const { // llassert(mTEImages); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index ea0d55cda5..16f1f403d3 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -339,6 +339,8 @@ public: LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; + bool isImageAlphaBlended(const U8 te) const; + void fitFaceTexture(const U8 face); void sendTEUpdate() const; // Sends packed representation of all texture entry information diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e9708fdba0..b030951840 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1219,7 +1219,7 @@ void LLViewerRegion::getInfo(LLSD& info) info["Region"]["Handle"]["y"] = (LLSD::Integer)y; } -void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) +void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) const { sim_features = mSimulatorFeatures; @@ -1945,3 +1945,47 @@ bool LLViewerRegion::dynamicPathfindingEnabled() const mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean()); } +void LLViewerRegion::resetMaterialsCapThrottle() +{ + F32 requests_per_sec = 1.0f; // original default; + if ( mSimulatorFeatures.has("RenderMaterialsCapability") + && mSimulatorFeatures["RenderMaterialsCapability"].isReal() ) + { + requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal(); + if ( requests_per_sec == 0.0f ) + { + requests_per_sec = 1.0f; + LL_WARNS("Materials") + << "region '" << getName() + << "' returned zero for RenderMaterialsCapability; using default " + << requests_per_sec << " per second" + << LL_ENDL; + } + LL_DEBUGS("Materials") << "region '" << getName() + << "' RenderMaterialsCapability " << requests_per_sec + << LL_ENDL; + } + else + { + LL_DEBUGS("Materials") + << "region '" << getName() + << "' did not return RenderMaterialsCapability, using default " + << requests_per_sec << " per second" + << LL_ENDL; + } + + mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec ); +} + +U32 LLViewerRegion::getMaxMaterialsPerTransaction() const +{ + U32 max_entries = 50; // original hard coded default + if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" ) + && mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger()) + { + max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger(); + } + return max_entries; +} + + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 56cd0c9ea1..109baccf9a 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -43,6 +43,7 @@ #include "llcapabilityprovider.h" #include "m4math.h" // LLMatrix4 #include "llhttpclient.h" +#include "llframetimer.h" // Surface id's #define LAND 1 @@ -293,7 +294,7 @@ public: bool meshRezEnabled() const; bool meshUploadEnabled() const; - void getSimulatorFeatures(LLSD& info); + void getSimulatorFeatures(LLSD& info) const; void setSimulatorFeatures(const LLSD& info); @@ -342,7 +343,12 @@ public: void getNeighboringRegionsStatus( std::vector<S32>& regions ); const LLViewerRegionImpl * getRegionImpl() const { return mImpl; } LLViewerRegionImpl * getRegionImplNC() { return mImpl; } + + // implements the materials capability throttle + bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); } + void resetMaterialsCapThrottle(); + U32 getMaxMaterialsPerTransaction() const; public: struct CompareDistance { @@ -434,6 +440,9 @@ private: BOOL mReleaseNotesRequested; LLSD mSimulatorFeatures; + + // the materials capability throttle + LLFrameTimer mMaterialsCapThrottleTimer; }; inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e24237522a..995eb599b8 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -42,22 +42,6 @@ #include "llvosky.h" #include "llrender.h" -#if LL_DARWIN -#include "OpenGL/OpenGL.h" - -// include spec exp clamp to fix older mac rendering artifacts -// -#define SINGLE_FP_PERMUTATION(shader) \ - if (gGLManager.mIsMobileGF) \ - { \ - shader.addPermutation("SINGLE_FP_ONLY","1"); \ - } - - -#else -#define SINGLE_FP_PERMUTATION(shader) -#endif - #ifdef LL_RELEASE_FOR_DOWNLOAD #define UNIFORM_ERRS LL_WARNS_ONCE("Shader") #else @@ -99,6 +83,7 @@ LLGLSLShader gAlphaMaskProgram; //object shaders LLGLSLShader gObjectSimpleProgram; +LLGLSLShader gObjectSimpleImpostorProgram; LLGLSLShader gObjectPreviewProgram; LLGLSLShader gObjectSimpleWaterProgram; LLGLSLShader gObjectSimpleAlphaMaskProgram; @@ -184,6 +169,7 @@ LLGLSLShader gPostNightVisionProgram; // Deferred rendering shaders LLGLSLShader gDeferredImpostorProgram; LLGLSLShader gDeferredWaterProgram; +LLGLSLShader gDeferredUnderWaterProgram; LLGLSLShader gDeferredDiffuseProgram; LLGLSLShader gDeferredDiffuseAlphaMaskProgram; LLGLSLShader gDeferredNonIndexedDiffuseProgram; @@ -199,20 +185,26 @@ LLGLSLShader gDeferredTreeShadowProgram; LLGLSLShader gDeferredAvatarProgram; LLGLSLShader gDeferredAvatarAlphaProgram; LLGLSLShader gDeferredLightProgram; -LLGLSLShader gDeferredMultiLightProgram; +LLGLSLShader gDeferredMultiLightProgram[16]; LLGLSLShader gDeferredSpotLightProgram; LLGLSLShader gDeferredMultiSpotLightProgram; LLGLSLShader gDeferredSunProgram; LLGLSLShader gDeferredBlurLightProgram; LLGLSLShader gDeferredSoftenProgram; +LLGLSLShader gDeferredSoftenWaterProgram; LLGLSLShader gDeferredShadowProgram; LLGLSLShader gDeferredShadowCubeProgram; LLGLSLShader gDeferredShadowAlphaMaskProgram; LLGLSLShader gDeferredAvatarShadowProgram; LLGLSLShader gDeferredAttachmentShadowProgram; LLGLSLShader gDeferredAlphaProgram; +LLGLSLShader gDeferredAlphaImpostorProgram; +LLGLSLShader gDeferredAlphaWaterProgram; LLGLSLShader gDeferredAvatarEyesProgram; LLGLSLShader gDeferredFullbrightProgram; +LLGLSLShader gDeferredFullbrightAlphaMaskProgram; +LLGLSLShader gDeferredFullbrightWaterProgram; +LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram; LLGLSLShader gDeferredEmissiveProgram; LLGLSLShader gDeferredPostProgram; LLGLSLShader gDeferredCoFProgram; @@ -230,6 +222,7 @@ LLGLSLShader gNormalMapGenProgram; // Deferred materials shaders LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; LLViewerShaderMgr::LLViewerShaderMgr() : mVertexShaderLevel(SHADER_COUNT, 0), @@ -245,6 +238,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gWaterProgram); mShaderList.push_back(&gAvatarEyeballProgram); mShaderList.push_back(&gObjectSimpleProgram); + mShaderList.push_back(&gObjectSimpleImpostorProgram); mShaderList.push_back(&gObjectPreviewProgram); mShaderList.push_back(&gImpostorProgram); mShaderList.push_back(&gObjectFullbrightNoColorProgram); @@ -295,6 +289,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gUnderWaterProgram); mShaderList.push_back(&gDeferredSunProgram); mShaderList.push_back(&gDeferredSoftenProgram); + mShaderList.push_back(&gDeferredSoftenWaterProgram); mShaderList.push_back(&gDeferredMaterialProgram[1]); mShaderList.push_back(&gDeferredMaterialProgram[5]); mShaderList.push_back(&gDeferredMaterialProgram[9]); @@ -303,15 +298,30 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT]); mShaderList.push_back(&gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT]); mShaderList.push_back(&gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT]); + mShaderList.push_back(&gDeferredMaterialWaterProgram[1]); + mShaderList.push_back(&gDeferredMaterialWaterProgram[5]); + mShaderList.push_back(&gDeferredMaterialWaterProgram[9]); + mShaderList.push_back(&gDeferredMaterialWaterProgram[13]); + mShaderList.push_back(&gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT]); + mShaderList.push_back(&gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT]); + mShaderList.push_back(&gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT]); + mShaderList.push_back(&gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT]); + mShaderList.push_back(&gDeferredAlphaProgram); mShaderList.push_back(&gDeferredAlphaProgram); + mShaderList.push_back(&gDeferredAlphaImpostorProgram); + mShaderList.push_back(&gDeferredAlphaWaterProgram); mShaderList.push_back(&gDeferredSkinnedAlphaProgram); mShaderList.push_back(&gDeferredFullbrightProgram); + mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram); + mShaderList.push_back(&gDeferredFullbrightWaterProgram); + mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram); mShaderList.push_back(&gDeferredFullbrightShinyProgram); mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); mShaderList.push_back(&gDeferredSkinnedFullbrightProgram); mShaderList.push_back(&gDeferredEmissiveProgram); mShaderList.push_back(&gDeferredAvatarEyesProgram); mShaderList.push_back(&gDeferredWaterProgram); + mShaderList.push_back(&gDeferredUnderWaterProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); @@ -721,6 +731,7 @@ void LLViewerShaderMgr::unloadShaders() gObjectFullbrightNoColorProgram.unload(); gObjectFullbrightNoColorWaterProgram.unload(); gObjectSimpleProgram.unload(); + gObjectSimpleImpostorProgram.unload(); gObjectPreviewProgram.unload(); gImpostorProgram.unload(); gObjectSimpleAlphaMaskProgram.unload(); @@ -1128,12 +1139,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredImpostorProgram.unload(); gDeferredTerrainProgram.unload(); gDeferredLightProgram.unload(); - gDeferredMultiLightProgram.unload(); + for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i) + { + gDeferredMultiLightProgram[i].unload(); + } gDeferredSpotLightProgram.unload(); gDeferredMultiSpotLightProgram.unload(); gDeferredSunProgram.unload(); gDeferredBlurLightProgram.unload(); gDeferredSoftenProgram.unload(); + gDeferredSoftenWaterProgram.unload(); gDeferredShadowProgram.unload(); gDeferredShadowCubeProgram.unload(); gDeferredShadowAlphaMaskProgram.unload(); @@ -1142,7 +1157,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarProgram.unload(); gDeferredAvatarAlphaProgram.unload(); gDeferredAlphaProgram.unload(); + gDeferredAlphaWaterProgram.unload(); gDeferredFullbrightProgram.unload(); + gDeferredFullbrightAlphaMaskProgram.unload(); + gDeferredFullbrightWaterProgram.unload(); + gDeferredFullbrightAlphaMaskWaterProgram.unload(); gDeferredEmissiveProgram.unload(); gDeferredAvatarEyesProgram.unload(); gDeferredPostProgram.unload(); @@ -1151,6 +1170,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPostGammaCorrectProgram.unload(); gFXAAProgram.unload(); gDeferredWaterProgram.unload(); + gDeferredUnderWaterProgram.unload(); gDeferredWLSkyProgram.unload(); gDeferredWLCloudProgram.unload(); gDeferredStarProgram.unload(); @@ -1162,6 +1182,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) { gDeferredMaterialProgram[i].unload(); + gDeferredMaterialWaterProgram[i].unload(); } return TRUE; } @@ -1170,7 +1191,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; + 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/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1246,11 +1267,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader"; - gDeferredSkinnedAlphaProgram.mFeatures.atmosphericHelpers = true; gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false; gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false; gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true; @@ -1260,8 +1277,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); - gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1"); + gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); @@ -1289,6 +1306,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) { if (success) @@ -1308,8 +1334,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() bool has_skin = i & 0x10; gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0"); - SINGLE_FP_PERMUTATION(gDeferredMaterialProgram[i]); - if (has_skin) { gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true; @@ -1317,6 +1341,34 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredMaterialProgram[i].createShader(NULL, NULL); } + + if (success) + { + gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i); + + U32 alpha_mode = i & 0x3; + + gDeferredMaterialWaterProgram[i].mShaderFiles.clear(); + gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMaterialWaterProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER; + + gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0"); + gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0"); + gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); + bool has_skin = i & 0x10; + gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0"); + gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1"); + + if (has_skin) + { + gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true; + } + + success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms); + } } gDeferredMaterialProgram[1].mFeatures.hasLighting = true; @@ -1328,6 +1380,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; if (success) @@ -1368,22 +1428,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - SINGLE_FP_PERMUTATION(gDeferredLightProgram); - success = gDeferredLightProgram.createShader(NULL, NULL); } - if (success) + for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++) { - 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - - SINGLE_FP_PERMUTATION(gDeferredMultiLightProgram); - - success = gDeferredMultiLightProgram.createShader(NULL, NULL); + if (success) + { + gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i); + gDeferredMultiLightProgram[i].mShaderFiles.clear(); + gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMultiLightProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1)); + success = gDeferredMultiLightProgram[i].createShader(NULL, NULL); + } } if (success) @@ -1394,8 +1453,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - SINGLE_FP_PERMUTATION(gDeferredSpotLightProgram); - success = gDeferredSpotLightProgram.createShader(NULL, NULL); } @@ -1407,8 +1464,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - SINGLE_FP_PERMUTATION(gDeferredMultiSpotLightProgram); - success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); } @@ -1436,8 +1491,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - SINGLE_FP_PERMUTATION(gDeferredSunProgram); - success = gDeferredSunProgram.createShader(NULL, NULL); } @@ -1449,19 +1502,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - SINGLE_FP_PERMUTATION(gDeferredBlurLightProgram); - success = gDeferredBlurLightProgram.createShader(NULL, NULL); } if (success) { gDeferredAlphaProgram.mName = "Deferred Alpha Shader"; - gDeferredAlphaProgram.mFeatures.atmosphericHelpers = true; + gDeferredAlphaProgram.mFeatures.calculatesLighting = false; - gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAlphaProgram.mFeatures.hasGamma = true; - gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredAlphaProgram.mFeatures.hasLighting = false; gDeferredAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels @@ -1478,12 +1526,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() 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)); gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1"); - gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); + gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - SINGLE_FP_PERMUTATION(gDeferredAlphaProgram); - success = gDeferredAlphaProgram.createShader(NULL, NULL); // Hack @@ -1493,6 +1539,72 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Shader"; + + gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false; + gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false; + gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true; + gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + if (mVertexShaderLevel[SHADER_DEFERRED] < 1) + { + gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + } + else + { //shave off some texture units for shadow maps + gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); + } + + gDeferredAlphaImpostorProgram.mShaderFiles.clear(); + gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1"); + gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); + gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1"); + gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1"); + + gDeferredAlphaImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + + success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL); + + // Hack + gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true; + gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true; + } + + if (success) + { + gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader"; + gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false; + gDeferredAlphaWaterProgram.mFeatures.hasLighting = false; + gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true; + gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + if (mVertexShaderLevel[SHADER_DEFERRED] < 1) + { + gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + } + else + { //shave off some texture units for shadow maps + gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); + } + gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredAlphaWaterProgram.mShaderFiles.clear(); + gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1"); + gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1"); + gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1"); + gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); + gDeferredAlphaWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + + success = gDeferredAlphaWaterProgram.createShader(NULL, NULL); + + // Hack + gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true; + gDeferredAlphaWaterProgram.mFeatures.hasLighting = true; + } + + if (success) + { gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; @@ -1521,6 +1633,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader"; + gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear(); + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1"); + gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader"; + gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true; + gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true; + gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightWaterProgram.mShaderFiles.clear(); + gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1"); + success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader"; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear(); + gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1"); + gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1"); + success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL); + } + + if (success) + { gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader"; gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true; @@ -1593,6 +1753,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + // load water shader + gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader"; + gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredUnderWaterProgram.mFeatures.hasGamma = true; + gDeferredUnderWaterProgram.mFeatures.hasTransport = true; + gDeferredUnderWaterProgram.mShaderFiles.clear(); + gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredUnderWaterProgram.createShader(NULL, &mWaterUniforms); + } + + if (success) + { gDeferredSoftenProgram.mName = "Deferred Soften Shader"; gDeferredSoftenProgram.mShaderFiles.clear(); gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1600,8 +1774,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - SINGLE_FP_PERMUTATION(gDeferredSoftenProgram); - if (gSavedSettings.getBOOL("RenderDeferredSSAO")) { //if using SSAO, take screen space light map into account as if shadows are enabled gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); @@ -1612,6 +1784,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader"; + gDeferredSoftenWaterProgram.mShaderFiles.clear(); + gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + + gDeferredSoftenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1"); + gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + + if (gSavedSettings.getBOOL("RenderDeferredSSAO")) + { //if using SSAO, take screen space light map into account as if shadows are enabled + gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2); + } + + success = gDeferredSoftenWaterProgram.createShader(NULL, &mWLUniforms); + } + + if (success) + { gDeferredShadowProgram.mName = "Deferred Shadow Shader"; gDeferredShadowProgram.mShaderFiles.clear(); gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1692,12 +1883,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader"; - gDeferredAvatarAlphaProgram.mFeatures.atmosphericHelpers = true; gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true; gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false; - gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; - gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false; gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; @@ -1836,6 +2023,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightNoColorProgram.unload(); gObjectFullbrightNoColorWaterProgram.unload(); gObjectSimpleProgram.unload(); + gObjectSimpleImpostorProgram.unload(); gObjectPreviewProgram.unload(); gImpostorProgram.unload(); gObjectSimpleAlphaMaskProgram.unload(); @@ -2258,6 +2446,27 @@ BOOL LLViewerShaderMgr::loadShadersObject() if (success) { + gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader"; + gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true; + gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleImpostorProgram.mFeatures.hasGamma = true; + gObjectSimpleImpostorProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleImpostorProgram.mFeatures.hasLighting = true; + gObjectSimpleImpostorProgram.mFeatures.mIndexedTextureChannels = 0; + // force alpha mask version of lighting so we can weed out + // transparent pixels from impostor temp buffer + // + gObjectSimpleImpostorProgram.mFeatures.hasAlphaMask = true; + gObjectSimpleImpostorProgram.mShaderFiles.clear(); + gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + + success = gObjectSimpleImpostorProgram.createShader(NULL, NULL); + } + + if (success) + { gObjectSimpleWaterProgram.mName = "Simple Water Shader"; gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; @@ -3191,3 +3400,4 @@ LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const { return mShaderList.end(); } + diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 438853cd6f..e4684c19d5 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -30,6 +30,8 @@ #include "llshadermgr.h" #include "llmaterial.h" +#define LL_DEFERRED_MULTI_LIGHT_COUNT 16 + class LLViewerShaderMgr: public LLShaderMgr { public: @@ -240,6 +242,7 @@ extern LLGLSLShader gOneTextureNoColorProgram; //object shaders extern LLGLSLShader gObjectSimpleProgram; +extern LLGLSLShader gObjectSimpleImpostorProgram; extern LLGLSLShader gObjectPreviewProgram; extern LLGLSLShader gObjectSimpleAlphaMaskProgram; extern LLGLSLShader gObjectSimpleWaterProgram; @@ -328,6 +331,7 @@ extern LLGLSLShader gPostNightVisionProgram; // Deferred rendering shaders extern LLGLSLShader gDeferredImpostorProgram; extern LLGLSLShader gDeferredWaterProgram; +extern LLGLSLShader gDeferredUnderWaterProgram; extern LLGLSLShader gDeferredDiffuseProgram; extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; @@ -341,13 +345,14 @@ extern LLGLSLShader gDeferredTerrainProgram; extern LLGLSLShader gDeferredTreeProgram; extern LLGLSLShader gDeferredTreeShadowProgram; extern LLGLSLShader gDeferredLightProgram; -extern LLGLSLShader gDeferredMultiLightProgram; +extern LLGLSLShader gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT]; extern LLGLSLShader gDeferredSpotLightProgram; extern LLGLSLShader gDeferredMultiSpotLightProgram; extern LLGLSLShader gDeferredSunProgram; extern LLGLSLShader gDeferredBlurLightProgram; extern LLGLSLShader gDeferredAvatarProgram; extern LLGLSLShader gDeferredSoftenProgram; +extern LLGLSLShader gDeferredSoftenWaterProgram; extern LLGLSLShader gDeferredShadowProgram; extern LLGLSLShader gDeferredShadowCubeProgram; extern LLGLSLShader gDeferredShadowAlphaMaskProgram; @@ -360,7 +365,12 @@ extern LLGLSLShader gDeferredPostGammaCorrectProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAttachmentShadowProgram; extern LLGLSLShader gDeferredAlphaProgram; +extern LLGLSLShader gDeferredAlphaImpostorProgram; extern LLGLSLShader gDeferredFullbrightProgram; +extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram; +extern LLGLSLShader gDeferredAlphaWaterProgram; +extern LLGLSLShader gDeferredFullbrightWaterProgram; +extern LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram; extern LLGLSLShader gDeferredEmissiveProgram; extern LLGLSLShader gDeferredAvatarEyesProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; @@ -374,5 +384,6 @@ extern LLGLSLShader gNormalMapGenProgram; // Deferred materials shaders extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; - +extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; #endif + diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d9f3548a29..d64db19733 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -562,11 +562,11 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) llassert(image); if (image->isInImageList()) { - llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl; + llinfos << "LLViewerTextureList::addImageToList - Image already in list" << llendl; } if((mImageList.insert(image)).second != true) { - llerrs << "Error happens when insert image to mImageList!" << llendl ; + llinfos << "Error happens when insert image to mImageList!" << llendl ; } image->setInImageList(TRUE) ; @@ -585,14 +585,14 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) { llinfos << "Image is not in mUUIDMap!" << llendl ; } - llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl; + llinfos << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl; } S32 count = mImageList.erase(image) ; + llassert(count == 1); if(count != 1) { - llinfos << image->getID() << llendl ; - llerrs << "Error happens when remove image from mImageList: " << count << llendl ; + llinfos << image->getID() << " removed with non-one count of " << count << llendl; } image->setInImageList(FALSE) ; @@ -602,15 +602,15 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image) { if (!new_image) { - llwarning("No image to add to image list", 0); return; } + llassert(new_image); LLUUID image_id = new_image->getID(); LLViewerFetchedTexture *image = findImage(image_id); if (image) { - llwarns << "Image with ID " << image_id << " already in list" << llendl; + llinfos << "Image with ID " << image_id << " already in list" << llendl; } sNumImages++; @@ -1237,7 +1237,7 @@ S32 LLViewerTextureList::getMinVideoRamSetting() //static // Returns max setting for TextureMemory (in MB) -S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) +S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier) { S32 max_texmem; if (gGLManager.mVRAM != 0) @@ -1282,6 +1282,9 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) else max_texmem = llmin(max_texmem, (S32)(system_ram)); + // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise + max_texmem = llmin(max_texmem, (S32) (mem_multiplier * (F32) max_texmem)); + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); return max_texmem; @@ -1294,7 +1297,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32 mem) // Initialize the image pipeline VRAM settings S32 cur_mem = gSavedSettings.getS32("TextureMemory"); F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); - S32 default_mem = getMaxVideoRamSetting(true); // recommended default + S32 default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default if (mem == 0) { mem = cur_mem > 0 ? cur_mem : default_mem; @@ -1304,10 +1307,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32 mem) mem = default_mem; } - // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise - mem = llmin(mem, (S32) (mem_multiplier * (F32) default_mem)); - - mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting()); + mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier)); if (mem != cur_mem) { gSavedSettings.setS32("TextureMemory", mem); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 136042620d..26dc6dcbe2 100755 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -114,7 +114,7 @@ public: void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level); static S32 getMinVideoRamSetting(); - static S32 getMaxVideoRamSetting(bool get_recommended = false); + static S32 getMaxVideoRamSetting(bool get_recommended, float mem_multiplier); private: void updateImagesDecodePriorities(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e6385dceea..6b3611b796 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1114,7 +1114,7 @@ void LLVOVolume::sculpt() S32 max_discard = mSculptTexture->getMaxDiscardLevel(); if (discard_level > max_discard) { - discard_level = max_discard; // clamp to the best we can do + discard_level = max_discard; // clamp to the best we can do } if(discard_level > MAX_DISCARD_LEVEL) { @@ -1458,7 +1458,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) continue; } res &= face->genVolumeBBoxes(*volume, i, - mRelativeXform, + mRelativeXform, /*mRelativeXformInvTrans,*/ (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); if (rebuild) @@ -2596,6 +2596,7 @@ void LLVOVolume::setLightTextureID(LLUUID id) if (hasLightTexture()) { setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); mLightTexture = NULL; } } @@ -2613,7 +2614,8 @@ void LLVOVolume::setSpotLightParams(LLVector3 params) void LLVOVolume::setIsLight(BOOL is_light) { - if (is_light != getIsLight()) + BOOL was_light = getIsLight(); + if (is_light != was_light) { if (is_light) { @@ -2798,7 +2800,7 @@ void LLVOVolume::updateSpotLightPriority() bool LLVOVolume::isLightSpotlight() const { LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (params) + if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) { return params->isLightSpotlight(); } @@ -3728,8 +3730,30 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { LLFace* face = mDrawable->getFace(face_hit); + bool ignore_alpha = false; + + const LLTextureEntry* te = face->getTextureEntry(); + if (te) + { + LLMaterial* mat = te->getMaterialParams(); + if (mat) + { + U8 mode = mat->getDiffuseAlphaMode(); + + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE || + mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE) + { + ignore_alpha = true; + } + } + } + if (face && - (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))) + (ignore_alpha || + pick_transparent || + !face->getTexture() || + !face->getTexture()->hasGLTexture() || + face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))) { local_end = p; if (face_hitp != NULL) @@ -4841,7 +4865,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (!drawablep->isState(LLDrawable::RIGGED)) { - drawablep->setState(LLDrawable::RIGGED); + drawablep->setState(LLDrawable::RIGGED); //first time this is drawable is being marked as rigged, // do another LoD update to use avatar bounding box @@ -5367,19 +5391,24 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; } - bool use_legacy_bump = te->getBumpmap() && (!mat || mat->getNormalID().isNull()); + bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull()); + bool opaque = te->getColor().mV[3] >= 0.999f; if (mat && LLPipeline::sRenderDeferred && !hud_group) { bool material_pass = false; - if (fullbright) + // do NOT use 'fullbright' for this logic or you risk sending + // things without normals down the materials pipeline and will + // render poorly if not crash NORSPEC-240,314 + // + if (te->getFullbright()) { if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { - if (te->getColor().mV[3] >= 0.999f) + if (opaque) { - material_pass = true; + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); } else { diff --git a/indra/newview/macutil_Prefix.h b/indra/newview/macutil_Prefix.h index b54a764a62..b8df961cac 100755 --- a/indra/newview/macutil_Prefix.h +++ b/indra/newview/macutil_Prefix.h @@ -32,7 +32,6 @@ * */ -#include <Carbon/Carbon.h> #include "fix_macros.h" #undef verify diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f49395da34..b4e59909db 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -111,6 +111,8 @@ #include "llpathinglib.h" #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindingcharacters.h" +#include "llfloatertools.h" +#include "llpanelface.h" #include "llpathfindingpathtool.h" #ifdef _DEBUG @@ -120,6 +122,10 @@ //#define DEBUG_INDICES #endif +// Expensive and currently broken +// +#define MATERIALS_IN_REFLECTIONS 0 + bool gShiftFrame = false; //cached settings @@ -374,6 +380,7 @@ BOOL LLPipeline::sWaterReflections = FALSE; BOOL LLPipeline::sRenderGlow = FALSE; BOOL LLPipeline::sReflectionRender = FALSE; BOOL LLPipeline::sImpostorRender = FALSE; +BOOL LLPipeline::sImpostorRenderAlphaDepthPass = FALSE; BOOL LLPipeline::sUnderWaterRender = FALSE; BOOL LLPipeline::sTextureBindTest = FALSE; BOOL LLPipeline::sRenderFrameTest = FALSE; @@ -789,14 +796,22 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - if (!allocateScreenBuffer(resX,resY)) - { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled - //NOTE: if the session closes successfully after this call, deferred rendering will be - // disabled on future sessions - if (LLPipeline::sRenderDeferred) + if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) + { + releaseScreenBuffers(); + if (!allocateScreenBuffer(resX,resY)) { - gSavedSettings.setBOOL("RenderDeferred", FALSE); - LLPipeline::refreshCachedSettings(); +#if PROBABLE_FALSE_DISABLES_OF_ALM_HERE + //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled + //NOTE: if the session closes successfully after this call, deferred rendering will be + // disabled on future sessions + if (LLPipeline::sRenderDeferred) + { + gSavedSettings.setBOOL("RenderDeferred", FALSE); + LLPipeline::refreshCachedSettings(); + + } +#endif } } } @@ -1186,7 +1201,8 @@ void LLPipeline::releaseGLBuffers() mWaterRef.release(); mWaterDis.release(); - + mHighlight.release(); + for (U32 i = 0; i < 3; i++) { mGlow[i].release(); @@ -1216,12 +1232,12 @@ void LLPipeline::releaseScreenBuffers() mDeferredScreen.release(); mDeferredDepth.release(); mDeferredLight.release(); - - mHighlight.release(); + mOcclusionDepth.release(); for (U32 i = 0; i < 6; i++) { mShadow[i].release(); + mShadowOcclusion[i].release(); } } @@ -1233,14 +1249,31 @@ void LLPipeline::createGLBuffers() updateRenderDeferred(); + bool materials_in_water = false; + +#if MATERIALS_IN_REFLECTIONS + materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); +#endif + if (LLPipeline::sWaterReflections) { //water reflection texture U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); + // Set up SRGB targets if we're doing deferred-path reflection rendering + // + if (LLPipeline::sRenderDeferred && materials_in_water) + { + mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE); + //always use FBO for mWaterDis so it can be used for avatar texture bakes + mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); + } + else + { mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); //always use FBO for mWaterDis so it can be used for avatar texture bakes mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); } + } mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); @@ -1402,9 +1435,15 @@ void LLPipeline::createLUTBuffers() } } - LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc); + U32 pix_format = GL_R16F; +#if LL_DARWIN + // Need to work around limited precision with 10.6.8 and older drivers + // + pix_format = GL_R32F; +#endif + LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, pix_format, 1, &mLightFunc); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); //LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); @@ -2443,7 +2482,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl if (to_texture) { - if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) + if (LLPipeline::sRenderDeferred) { mOcclusionDepth.bindTarget(); } @@ -2588,7 +2627,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl if (to_texture) { - if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) + if (LLPipeline::sRenderDeferred) { mOcclusionDepth.flush(); } @@ -3959,7 +3998,7 @@ void LLPipeline::postSort(LLCamera& camera) { mSelectedFaces.clear(); - LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel()); + LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit()); // Draw face highlights for selected faces. if (LLSelectMgr::getInstance()->getTEMode()) @@ -5383,7 +5422,7 @@ void LLPipeline::renderDebug() if (i > 3) { //render shadow frusta as volumes if (mShadowFrustPoints[i-4].empty()) - { + { continue; } @@ -8527,7 +8566,7 @@ void LLPipeline::renderDeferredLighting() if (RenderDeferredAtmospheric) { //apply sunlight contribution LLFastTimer ftm(FTM_ATMOSPHERICS); - bindDeferredShader(gDeferredSoftenProgram); + bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram); { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -8549,7 +8588,7 @@ void LLPipeline::renderDeferredLighting() gGL.popMatrix(); } - unbindDeferredShader(gDeferredSoftenProgram); + unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram); } { //render non-deferred geometry (fullbright, alpha, etc) @@ -8742,10 +8781,6 @@ void LLPipeline::renderDeferredLighting() vert[2].set(3,1,0); { - bindDeferredShader(gDeferredMultiLightProgram); - - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - LLGLDepthTest depth(GL_FALSE); //full screen blit @@ -8757,7 +8792,7 @@ void LLPipeline::renderDeferredLighting() U32 count = 0; - const U32 max_count = 8; + const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; LLVector4 light[max_count]; LLVector4 col[max_count]; @@ -8780,18 +8815,20 @@ void LLPipeline::renderDeferredLighting() count++; if (count == max_count || fullscreen_lights.empty()) { - gDeferredMultiLightProgram.uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); - gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); - gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); - gDeferredMultiLightProgram.uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); + U32 idx = count-1; + bindDeferredShader(gDeferredMultiLightProgram[idx]); + gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); + gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); + gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); + gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); far_z = 0.f; count = 0; + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + unbindDeferredShader(gDeferredMultiLightProgram[idx]); } } - unbindDeferredShader(gDeferredMultiLightProgram); - bindDeferredShader(gDeferredMultiSpotLightProgram); gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); @@ -8872,9 +8909,9 @@ void LLPipeline::renderDeferredLighting() gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); - F32 gamma = 1.0/2.2; + F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); - gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, gamma); + gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); gGL.begin(LLRender::TRIANGLE_STRIP); gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); @@ -8953,6 +8990,537 @@ void LLPipeline::renderDeferredLighting() } +void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) +{ + if (!sCull) + { + return; + } + + { + LLFastTimer ftm(FTM_RENDER_DEFERRED); + + LLViewerCamera* camera = LLViewerCamera::getInstance(); + + { + LLGLDepthTest depth(GL_TRUE); + mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), + 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } + + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + } + + //ati doesn't seem to love actually using the stencil buffer on FBO's + LLGLDisable stencil(GL_STENCIL_TEST); + //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); + //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + gGL.setColorMask(true, true); + + //draw a cube around every light + LLVertexBuffer::unbind(); + + LLGLEnable cull(GL_CULL_FACE); + LLGLEnable blend(GL_BLEND); + + glh::matrix4f mat = glh_copy_matrix(gGLModelView); + + LLStrider<LLVector3> vert; + mDeferredVB->getVertexStrider(vert); + + vert[0].set(-1,1,0); + vert[1].set(-1,-3,0); + vert[2].set(3,1,0); + + { + setupHWLights(NULL); //to set mSunDir; + LLVector4 dir(mSunDir, 0.f); + glh::vec4f tc(dir.mV); + mat.mult_matrix_vec(tc); + mTransformedSunDir.set(tc.v); + } + + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + + if (RenderDeferredSSAO || RenderShadowDetail > 0) + { + mDeferredLight.bindTarget(); + { //paint shadow/SSAO light map (direct lighting lightmap) + LLFastTimer ftm(FTM_SUN_SHADOW); + bindDeferredShader(gDeferredSunProgram); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + glClearColor(1,1,1,1); + mDeferredLight.clear(GL_COLOR_BUFFER_BIT); + glClearColor(0,0,0,0); + + glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + + const U32 slice = 32; + F32 offset[slice*3]; + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 8; j++) + { + glh::vec3f v; + v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); + v.normalize(); + inv_trans.mult_matrix_vec(v); + v.normalize(); + offset[(i*8+j)*3+0] = v.v[0]; + offset[(i*8+j)*3+1] = v.v[2]; + offset[(i*8+j)*3+2] = v.v[1]; + } + } + + gDeferredSunProgram.uniform3fv("offset", slice, offset); + gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight()); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); + } + + unbindDeferredShader(gDeferredSunProgram); + } + mDeferredLight.flush(); + } + + stop_glerror(); + gGL.popMatrix(); + stop_glerror(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + stop_glerror(); + gGL.popMatrix(); + stop_glerror(); + + target->bindTarget(); + + //clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); + target->clear(GL_COLOR_BUFFER_BIT); + + if (RenderDeferredAtmospheric) + { //apply sunlight contribution + LLFastTimer ftm(FTM_ATMOSPHERICS); + bindDeferredShader(gDeferredSoftenProgram); + { + LLGLDepthTest depth(GL_FALSE); + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + + //full screen blit + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + } + + unbindDeferredShader(gDeferredSoftenProgram); + } + + { //render non-deferred geometry (fullbright, alpha, etc) + LLGLDisable blend(GL_BLEND); + LLGLDisable stencil(GL_STENCIL_TEST); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + gPipeline.pushRenderTypeMask(); + + gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); + + + renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); + gPipeline.popRenderTypeMask(); + } + + BOOL render_local = RenderLocalLights; + + if (render_local) + { + gGL.setSceneBlendType(LLRender::BT_ADD); + std::list<LLVector4> fullscreen_lights; + LLDrawable::drawable_list_t spot_lights; + LLDrawable::drawable_list_t fullscreen_spot_lights; + + for (U32 i = 0; i < 2; i++) + { + mTargetShadowSpotLight[i] = NULL; + } + + std::list<LLVector4> light_colors; + + LLVertexBuffer::unbind(); + + { + bindDeferredShader(gDeferredLightProgram); + + if (mCubeVB.isNull()) + { + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); + } + + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) + { + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + if (!volume) + { + continue; + } + + if (volume->isAttachment()) + { + if (!sRenderAttachedLights) + { + continue; + } + } + + + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); + F32 s = volume->getLightRadius()*1.5f; + + LLColor3 col = volume->getLightColor(); + + if (col.magVecSquared() < 0.001f) + { + continue; + } + + if (s <= 0.001f) + { + continue; + } + + LLVector4a sa; + sa.splat(s); + if (camera->AABBInFrustumNoFarClip(center, sa) == 0) + { + continue; + } + + sVisibleLightCount++; + + if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || + camera->getOrigin().mV[0] < c[0] - s - 0.2f || + camera->getOrigin().mV[1] > c[1] + s + 0.2f || + camera->getOrigin().mV[1] < c[1] - s - 0.2f || + camera->getOrigin().mV[2] > c[2] + s + 0.2f || + camera->getOrigin().mV[2] < c[2] - s - 0.2f) + { //draw box if camera is outside box + if (render_local) + { + if (volume->isLightSpotlight()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + spot_lights.push_back(drawablep); + continue; + } + + /*col.mV[0] = powf(col.mV[0], 2.2f); + col.mV[1] = powf(col.mV[1], 2.2f); + col.mV[2] = powf(col.mV[2], 2.2f);*/ + + LLFastTimer ftm(FTM_LOCAL_LIGHTS); + gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); + gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); + gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); + gGL.syncMatrices(); + + mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); + stop_glerror(); + } + } + else + { + if (volume->isLightSpotlight()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + fullscreen_spot_lights.push_back(drawablep); + continue; + } + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); + light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); + } + } + unbindDeferredShader(gDeferredLightProgram); + } + + if (!spot_lights.empty()) + { + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + bindDeferredShader(gDeferredSpotLightProgram); + + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + + for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) + { + LLFastTimer ftm(FTM_PROJECTORS); + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); + F32 s = volume->getLightRadius()*1.5f; + + sVisibleLightCount++; + + setupSpotLight(gDeferredSpotLightProgram, drawablep); + + LLColor3 col = volume->getLightColor(); + /*col.mV[0] = powf(col.mV[0], 2.2f); + col.mV[1] = powf(col.mV[1], 2.2f); + col.mV[2] = powf(col.mV[2], 2.2f);*/ + + gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); + gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); + gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); + gGL.syncMatrices(); + + mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); + } + gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredSpotLightProgram); + } + + //reset mDeferredVB to fullscreen triangle + mDeferredVB->getVertexStrider(vert); + vert[0].set(-1,1,0); + vert[1].set(-1,-3,0); + vert[2].set(3,1,0); + + { + LLGLDepthTest depth(GL_FALSE); + + //full screen blit + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + + U32 count = 0; + + const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; + LLVector4 light[max_count]; + LLVector4 col[max_count]; + + F32 far_z = 0.f; + + while (!fullscreen_lights.empty()) + { + LLFastTimer ftm(FTM_FULLSCREEN_LIGHTS); + light[count] = fullscreen_lights.front(); + fullscreen_lights.pop_front(); + col[count] = light_colors.front(); + light_colors.pop_front(); + + /*col[count].mV[0] = powf(col[count].mV[0], 2.2f); + col[count].mV[1] = powf(col[count].mV[1], 2.2f); + col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/ + + far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z); + //col[count] = pow4fsrgb(col[count], 2.2f); + count++; + if (count == max_count || fullscreen_lights.empty()) + { + U32 idx = count-1; + bindDeferredShader(gDeferredMultiLightProgram[idx]); + gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); + gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); + gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); + gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); + far_z = 0.f; + count = 0; + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + } + + unbindDeferredShader(gDeferredMultiLightProgram[0]); + + bindDeferredShader(gDeferredMultiSpotLightProgram); + + gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) + { + LLFastTimer ftm(FTM_PROJECTORS); + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + + LLColor3 col = volume->getLightColor(); + + /*col.mV[0] = powf(col.mV[0], 2.2f); + col.mV[1] = powf(col.mV[1], 2.2f); + col.mV[2] = powf(col.mV[2], 2.2f);*/ + + gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); + gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + + gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredMultiSpotLightProgram); + + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + } + } + + gGL.setColorMask(true, true); + } + + /*target->flush(); + + //gamma correct lighting + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); + + { + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + + LLVector2 tc1(0,0); + LLVector2 tc2((F32) target->getWidth()*2, + (F32) target->getHeight()*2); + + target->bindTarget(); + // Apply gamma correction to the frame here. + gDeferredPostGammaCorrectProgram.bind(); + //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + S32 channel = 0; + channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage()); + if (channel > -1) + { + target->bindTexture(0,channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight()); + + F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + + gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + + gGL.getTexUnit(channel)->unbind(target->getUsage()); + gDeferredPostGammaCorrectProgram.unbind(); + target->flush(); + } + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + + target->bindTarget();*/ + + { //render non-deferred geometry (alpha, fullbright, glow) + LLGLDisable blend(GL_BLEND); + LLGLDisable stencil(GL_STENCIL_TEST); + + pushRenderTypeMask(); + andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_GLOW, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_POST_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + LLPipeline::RENDER_TYPE_PASS_GLOW, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_INVISIBLE, + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_ALPHA_MASK, + LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, + END_RENDER_TYPES); + + renderGeomPostDeferred(*LLViewerCamera::getInstance()); + popRenderTypeMask(); + } + + //target->flush(); +} + void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) { //construct frustum @@ -9199,6 +9767,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) water_clip = 1; } + bool materials_in_water = false; + +#if MATERIALS_IN_REFLECTIONS + materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); +#endif + if (!LLViewerCamera::getInstance()->cameraUnderWater()) { //generate planar reflection map @@ -9207,7 +9781,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLPipeline::sUseOcclusion = 0; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glClearColor(0,0,0,0); + mWaterRef.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0; gGL.setColorMask(true, true); mWaterRef.clear(); @@ -9256,11 +9832,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) updateCull(camera, result); stateSort(camera, result); + if (LLPipeline::sRenderDeferred && materials_in_water) + { + mWaterRef.flush(); + + gPipeline.grabReferences(result); + gPipeline.mDeferredScreen.bindTarget(); + gGL.setColorMask(true, true); + glClearColor(0,0,0,0); + gPipeline.mDeferredScreen.clear(); + + renderGeomDeferred(camera); + } + else + { renderGeom(camera, TRUE); + } gPipeline.popRenderTypeMask(); } + gGL.setColorMask(true, false); gPipeline.pushRenderTypeMask(); clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, @@ -9298,9 +9890,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { gPipeline.grabReferences(ref_result); LLGLUserClipPlane clip_plane(plane, mat, projection); + + if (LLPipeline::sRenderDeferred && materials_in_water) + { + renderGeomDeferred(camera); + } + else + { renderGeom(camera); } } + } + + if (LLPipeline::sRenderDeferred && materials_in_water) + { + gPipeline.mDeferredScreen.flush(); + renderDeferredLightingToRT(&mWaterRef); + } gPipeline.popRenderTypeMask(); } @@ -9336,10 +9942,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLViewerCamera::updateFrustumPlanes(camera); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLColor4& col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); mWaterDis.bindTarget(); LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; + mWaterDis.getViewport(gGLViewport); if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) @@ -9355,14 +9963,36 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.setColorMask(true, true); mWaterDis.clear(); + + gGL.setColorMask(true, false); + + if (LLPipeline::sRenderDeferred && materials_in_water) + { + mWaterDis.flush(); + gPipeline.mDeferredScreen.bindTarget(); + gGL.setColorMask(true, true); + glClearColor(0,0,0,0); + gPipeline.mDeferredScreen.clear(); + gPipeline.grabReferences(result); + renderGeomDeferred(camera); + } + else + { renderGeom(camera); + } + if (LLPipeline::sRenderDeferred && materials_in_water) + { + gPipeline.mDeferredScreen.flush(); + renderDeferredLightingToRT(&mWaterDis); + } } - LLPipeline::sUnderWaterRender = FALSE; mWaterDis.flush(); + LLPipeline::sUnderWaterRender = FALSE; + } last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; @@ -9769,14 +10399,14 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector const LLPlane& cp = camera.getAgentPlane(j); F32 dist = cp.dist(pp[i]); if (dist > 0.05f) //point is above some plane, not contained - { + { found = false; break; - } - } + } + } - if (found) - { + if (found) + { fp.push_back(pp[i]); } } @@ -10688,29 +11318,37 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) } else { - andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, - LLPipeline::RENDER_TYPE_AVATAR, + andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_GLOW, LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_GRASS, - LLPipeline::RENDER_TYPE_SIMPLE, - LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_ALPHA, - LLPipeline::RENDER_TYPE_INVISIBLE, LLPipeline::RENDER_TYPE_PASS_SIMPLE, LLPipeline::RENDER_TYPE_PASS_ALPHA, LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_POST_BUMP, LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + LLPipeline::RENDER_TYPE_PASS_GLOW, + LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SHINY, LLPipeline::RENDER_TYPE_PASS_INVISIBLE, LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_ALPHA_MASK, + LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_INVISIBLE, + LLPipeline::RENDER_TYPE_SIMPLE, END_RENDER_TYPES); } S32 occlusion = sUseOcclusion; sUseOcclusion = 0; + sReflectionRender = sRenderDeferred ? FALSE : TRUE; + sShadowRender = TRUE; sImpostorRender = TRUE; @@ -10805,22 +11443,26 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (!avatar->mImpostor.isComplete()) { LLFastTimer t(FTM_IMPOSTOR_ALLOCATE); - avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); + if (LLPipeline::sRenderDeferred) { + avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE); addDeferredAttachments(avatar->mImpostor); } + else + { + avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); + } gGL.getTexUnit(0)->bind(&avatar->mImpostor); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } - else if(resX != avatar->mImpostor.getWidth() || - resY != avatar->mImpostor.getHeight()) + else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) { LLFastTimer t(FTM_IMPOSTOR_RESIZE); - avatar->mImpostor.resize(resX,resY,GL_RGBA); + avatar->mImpostor.resize(resX,resY); } avatar->mImpostor.bindTarget(); @@ -10830,7 +11472,23 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) { avatar->mImpostor.clear(); renderGeomDeferred(camera); + + renderGeomPostDeferred(camera); + + // Shameless hack time: render it all again, + // this time writing the depth + // values we need to generate the alpha mask below + // while preserving the alpha-sorted color rendering + // from the previous pass + // + sImpostorRenderAlphaDepthPass = true; + // depth-only here... + // + gGL.setColorMask(false,false); renderGeomPostDeferred(camera); + + sImpostorRenderAlphaDepthPass = false; + } else { @@ -10838,10 +11496,26 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) glScissor(0, 0, resX, resY); avatar->mImpostor.clear(); renderGeom(camera); + + // Shameless hack time: render it all again, + // this time writing the depth + // values we need to generate the alpha mask below + // while preserving the alpha-sorted color rendering + // from the previous pass + // + sImpostorRenderAlphaDepthPass = true; + + // depth-only here... + // + gGL.setColorMask(false,false); + renderGeom(camera); + + sImpostorRenderAlphaDepthPass = false; } { //create alpha mask based on depth buffer (grey out if muted) LLFastTimer t(FTM_IMPOSTOR_BACKGROUND); + if (LLPipeline::sRenderDeferred) { GLuint buff = GL_COLOR_ATTACHMENT0; @@ -11226,6 +11900,3 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id ) } } - - - diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index f0bebbe20d..fbbcf8f06d 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -295,7 +295,8 @@ public: void unbindDeferredShader(LLGLSLShader& shader); void renderDeferredLighting(); - + void renderDeferredLightingToRT(LLRenderTarget* target); + void generateWaterReflection(LLCamera& camera); void generateSunShadow(LLCamera& camera); void generateHighlight(LLCamera& camera); @@ -594,6 +595,7 @@ public: static BOOL sPickAvatar; static BOOL sReflectionRender; static BOOL sImpostorRender; + static BOOL sImpostorRenderAlphaDepthPass; static BOOL sUnderWaterRender; static BOOL sRenderGlow; static BOOL sTextureBindTest; diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 5ac2ec2b20..426c0c4915 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -663,7 +663,7 @@ label_width="205" layout="topleft" left="10" - min_val="-1" + min_val="0" name="bumpyOffsetU" width="265" /> <spinner @@ -674,7 +674,7 @@ label_width="205" layout="topleft" left="10" - min_val="-1" + min_val="0" name="bumpyOffsetV" width="265" /> <spinner @@ -726,7 +726,7 @@ label_width="205" layout="topleft" left="10" - min_val="-1" + min_val="0" name="shinyOffsetU" width="265" /> <spinner @@ -737,7 +737,7 @@ label_width="205" layout="topleft" left="10" - min_val="-1" + min_val="0" name="shinyOffsetV" width="265" /> <check_box |