summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autobuild.xml1293
-rwxr-xr-xdoc/contributions.txt11
-rw-r--r--indra/CMakeLists.txt7
-rw-r--r--indra/cmake/00-Common.cmake2
-rw-r--r--indra/cmake/APR.cmake5
-rw-r--r--indra/cmake/BerkeleyDB.cmake17
-rw-r--r--indra/cmake/Boost.cmake75
-rw-r--r--indra/cmake/CMakeLists.txt6
-rw-r--r--indra/cmake/FindBerkeleyDB.cmake50
-rw-r--r--indra/cmake/FindZLIB.cmake46
-rw-r--r--indra/cmake/FindZLIBNG.cmake46
-rw-r--r--indra/cmake/GLEXT.cmake4
-rw-r--r--indra/cmake/LLAppearanceUtility.cmake2
-rw-r--r--indra/cmake/LLCommon.cmake2
-rw-r--r--indra/cmake/LLMath.cmake4
-rw-r--r--indra/cmake/LLPrimitive.cmake5
-rw-r--r--indra/cmake/LLRender.cmake2
-rw-r--r--indra/cmake/Mikktspace.cmake6
-rw-r--r--indra/cmake/TinyGLTF.cmake7
-rw-r--r--indra/cmake/VulkanGltf.cmake5
-rw-r--r--indra/cmake/ZLIBNG.cmake (renamed from indra/cmake/ZLIB.cmake)20
-rw-r--r--indra/doxygen/CMakeLists.txt2
-rwxr-xr-xindra/lib/python/indra/util/llmanifest.py3
-rw-r--r--indra/llappearance/llavatarappearance.cpp4
-rw-r--r--indra/llappearance/llpolymesh.cpp8
-rw-r--r--indra/llappearance/llpolymorph.cpp4
-rw-r--r--indra/llappearance/lltexlayer.cpp35
-rw-r--r--indra/llappearance/lltexlayer.h2
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudiodecodemgr.cpp346
-rw-r--r--indra/llaudio/llaudiodecodemgr.h15
-rw-r--r--indra/llaudio/llaudioengine.cpp114
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudioengine.h75
-rw-r--r--indra/llaudio/llaudioengine_fmodstudio.cpp18
-rw-r--r--indra/llaudio/llaudioengine_fmodstudio.h2
-rw-r--r--indra/llaudio/llaudioengine_openal.cpp6
-rw-r--r--indra/llaudio/llaudioengine_openal.h2
-rw-r--r--indra/llaudio/llstreamingaudio_fmodstudio.cpp33
-rw-r--r--indra/llcharacter/llbvhloader.cpp26
-rw-r--r--indra/llcharacter/llkeyframemotion.cpp45
-rw-r--r--indra/llcharacter/llkeyframemotion.h7
-rw-r--r--indra/llcommon/CMakeLists.txt25
-rw-r--r--indra/llcommon/classic_callback.cpp16
-rw-r--r--indra/llcommon/classic_callback.h292
-rw-r--r--indra/llcommon/llalignedarray.h10
-rw-r--r--indra/llcommon/llassettype.cpp1
-rw-r--r--indra/llcommon/llassettype.h5
-rw-r--r--indra/llcommon/llcoros.cpp37
-rw-r--r--indra/llcommon/llcoros.h35
-rw-r--r--indra/llcommon/llmemory.cpp8
-rw-r--r--indra/llcommon/llprocessor.cpp139
-rw-r--r--indra/llcommon/llprocessor.h5
-rw-r--r--indra/llcommon/llprofiler.h37
-rw-r--r--indra/llcommon/llqueuedthread.cpp2
-rw-r--r--indra/llcommon/llrefcount.cpp2
-rw-r--r--indra/llcommon/llsdserialize.cpp2
-rw-r--r--indra/llcommon/llsys.cpp118
-rw-r--r--indra/llcommon/llsys.h16
-rw-r--r--indra/llcommon/llsys_objc.h33
-rw-r--r--indra/llcommon/llsys_objc.mm64
-rw-r--r--indra/llcommon/lltimer.cpp28
-rw-r--r--indra/llcommon/llworkerthread.cpp2
-rw-r--r--indra/llcommon/tests/classic_callback_test.cpp144
-rw-r--r--indra/llcommon/workqueue.h8
-rw-r--r--indra/llcorehttp/CMakeLists.txt2
-rw-r--r--indra/llfilesystem/lldiskcache.cpp70
-rw-r--r--indra/llfilesystem/lldiskcache.h2
-rw-r--r--indra/llimage/CMakeLists.txt6
-rw-r--r--indra/llimage/llimage.cpp9
-rw-r--r--indra/llimage/llimage.h1
-rw-r--r--indra/llinventory/llfoldertype.cpp1
-rw-r--r--indra/llinventory/llfoldertype.h4
-rw-r--r--indra/llinventory/llinventorytype.cpp4
-rw-r--r--indra/llinventory/llinventorytype.h5
-rw-r--r--indra/llinventory/llparcel.cpp7
-rw-r--r--indra/llinventory/llparcel.h4
-rw-r--r--indra/llinventory/llsettingssky.cpp17
-rw-r--r--indra/llinventory/llsettingssky.h6
-rw-r--r--indra/llmath/CMakeLists.txt3
-rw-r--r--indra/llmath/lloctree.h153
-rw-r--r--indra/llmath/llvolume.cpp624
-rw-r--r--indra/llmath/llvolume.h33
-rw-r--r--indra/llmath/llvolumeoctree.cpp18
-rw-r--r--indra/llmath/llvolumeoctree.h20
-rw-r--r--indra/llmath/v3color.h51
-rw-r--r--indra/llmath/v4color.h41
-rw-r--r--indra/llmeshoptimizer/llmeshoptimizer.cpp215
-rw-r--r--indra/llmeshoptimizer/llmeshoptimizer.h81
-rw-r--r--indra/llmessage/llavatarnamecache.cpp4
-rw-r--r--indra/llmessage/llcoproceduremanager.h3
-rw-r--r--indra/llmessage/lldatapacker.cpp6
-rw-r--r--indra/llmessage/llpartdata.cpp5
-rw-r--r--indra/llmessage/llthrottle.cpp2
-rw-r--r--indra/llmessage/message_prehash.cpp4
-rw-r--r--indra/llmessage/message_prehash.h3
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp1
-rw-r--r--indra/llplugin/llpluginclassmedia.h2
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp2
-rw-r--r--indra/llprimitive/CMakeLists.txt9
-rw-r--r--indra/llprimitive/lldaeloader.cpp47
-rw-r--r--indra/llprimitive/lldaeloader.h3
-rw-r--r--indra/llprimitive/llgltfloader.cpp402
-rw-r--r--indra/llprimitive/llgltfloader.h206
-rw-r--r--indra/llprimitive/llgltfmaterial.cpp557
-rw-r--r--indra/llprimitive/llgltfmaterial.h193
-rw-r--r--indra/llprimitive/llmaterial.cpp11
-rw-r--r--indra/llprimitive/llmaterial.h6
-rw-r--r--indra/llprimitive/llmaterialid.cpp7
-rw-r--r--indra/llprimitive/llmaterialid.h1
-rw-r--r--indra/llprimitive/llmodel.cpp107
-rw-r--r--indra/llprimitive/llmodel.h11
-rw-r--r--indra/llprimitive/llmodelloader.cpp13
-rw-r--r--indra/llprimitive/llprimitive.cpp264
-rw-r--r--indra/llprimitive/llprimitive.h79
-rw-r--r--indra/llprimitive/lltextureentry.cpp81
-rw-r--r--indra/llprimitive/lltextureentry.h25
-rw-r--r--indra/llprimitive/tests/llmessagesystem_stub.cpp2
-rw-r--r--indra/llprimitive/tests/llprimitive_test.cpp40
-rw-r--r--indra/llrender/CMakeLists.txt2
-rw-r--r--indra/llrender/llatmosphere.cpp8
-rw-r--r--indra/llrender/llcubemap.cpp275
-rw-r--r--indra/llrender/llcubemap.h24
-rw-r--r--indra/llrender/llcubemaparray.cpp165
-rw-r--r--indra/llrender/llcubemaparray.h68
-rw-r--r--indra/llrender/llgl.cpp2620
-rw-r--r--indra/llrender/llgl.h62
-rw-r--r--indra/llrender/llglcommonfunc.cpp5
-rw-r--r--indra/llrender/llglheaders.h1282
-rw-r--r--indra/llrender/llglslshader.cpp289
-rw-r--r--indra/llrender/llglslshader.h30
-rw-r--r--indra/llrender/llglstates.h2
-rw-r--r--indra/llrender/llimagegl.cpp161
-rw-r--r--indra/llrender/llimagegl.h9
-rw-r--r--indra/llrender/llpostprocess.cpp68
-rw-r--r--indra/llrender/llpostprocess.h4
-rw-r--r--indra/llrender/llrender.cpp199
-rw-r--r--indra/llrender/llrender.h13
-rw-r--r--indra/llrender/llrender2dutils.cpp10
-rw-r--r--indra/llrender/llrendertarget.cpp44
-rw-r--r--indra/llrender/llshadermgr.cpp175
-rw-r--r--indra/llrender/llshadermgr.h32
-rw-r--r--indra/llrender/llvertexbuffer.cpp419
-rw-r--r--indra/llrender/llvertexbuffer.h12
-rw-r--r--indra/llui/llbutton.cpp20
-rw-r--r--indra/llui/llbutton.h2
-rw-r--r--indra/llui/llfloater.cpp35
-rw-r--r--indra/llui/llfloater.h1
-rw-r--r--indra/llui/lliconctrl.cpp13
-rw-r--r--indra/llui/lliconctrl.h7
-rw-r--r--indra/llui/lllayoutstack.cpp2
-rw-r--r--indra/llui/llmenubutton.cpp8
-rw-r--r--indra/llui/llmenubutton.h3
-rw-r--r--indra/llui/llmenugl.cpp20
-rw-r--r--indra/llui/llmodaldialog.cpp14
-rw-r--r--indra/llui/llprogressbar.cpp24
-rw-r--r--indra/llui/llscrolllistctrl.cpp88
-rw-r--r--indra/llui/llscrolllistctrl.h10
-rw-r--r--indra/llui/llspinctrl.cpp2
-rw-r--r--indra/llui/lltabcontainer.cpp18
-rw-r--r--indra/llui/lltextbase.cpp51
-rw-r--r--indra/llui/lltextbase.h9
-rw-r--r--indra/llui/lltexteditor.h1
-rw-r--r--indra/llui/lltextutil.cpp16
-rw-r--r--indra/llui/lltextutil.h12
-rw-r--r--indra/llui/llui.h3
-rw-r--r--indra/llui/llurlaction.cpp9
-rw-r--r--indra/llui/llurlaction.h1
-rw-r--r--indra/llwindow/CMakeLists.txt6
-rw-r--r--indra/llwindow/lldxhardware.cpp78
-rw-r--r--indra/llwindow/lldxhardware.h10
-rw-r--r--indra/llwindow/llkeyboard.cpp16
-rw-r--r--indra/llwindow/llkeyboard.h3
-rw-r--r--indra/llwindow/llopenglview-objc.mm7
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm4
-rw-r--r--indra/llwindow/llwindowmacosx.cpp11
-rw-r--r--indra/llwindow/llwindowwin32.cpp145
-rw-r--r--indra/mac_crash_logger/README.txt3
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp24
-rw-r--r--indra/media_plugins/libvlc/media_plugin_libvlc.cpp80
-rw-r--r--indra/newview/CMakeLists.txt61
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/cmd_line.xml2
-rw-r--r--indra/newview/app_settings/commands.xml6
-rw-r--r--indra/newview/app_settings/high_graphics.xml41
-rw-r--r--indra/newview/app_settings/key_bindings.xml1
-rw-r--r--indra/newview/app_settings/logcontrol.xml1
-rw-r--r--indra/newview/app_settings/low_graphics.xml41
-rw-r--r--indra/newview/app_settings/mid_graphics.xml41
-rw-r--r--indra/newview/app_settings/settings.xml253
-rw-r--r--indra/newview/app_settings/settings_per_account.xml11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl298
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl127
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl490
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl141
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl)16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl419
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl)17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl115
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl105
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl92
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterF.glsl164
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterF.glsl141
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterV.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl227
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl)19
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl169
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/skyV.glsl)19
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl101
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl117
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl127
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl306
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl239
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl75
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/skyF.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/waterF.glsl192
-rw-r--r--indra/newview/app_settings/shaders/class2/environment/waterF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/waterF.glsl)68
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl251
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/transportF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl134
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl52
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl68
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl119
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl166
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl79
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl202
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl106
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl111
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/indirect.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl380
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl195
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl)19
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl323
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl156
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl)29
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl572
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl73
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl157
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl62
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/skyF.glsl126
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl261
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl351
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl59
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterV.glsl95
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl)70
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl265
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl73
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl51
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/transportF.glsl68
-rw-r--r--indra/newview/app_settings/shaders/shader_hierarchy.txt184
-rw-r--r--indra/newview/app_settings/ultra_graphics.xml42
-rw-r--r--indra/newview/character/avatar_skeleton.xml214
-rw-r--r--indra/newview/cube.dae103
-rw-r--r--indra/newview/featuretable.txt83
-rw-r--r--indra/newview/featuretable_mac.txt64
-rw-r--r--indra/newview/installers/windows/installer_template.nsi36
-rw-r--r--indra/newview/installers/windows/lang_da.nsibin11992 -> 12802 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_de.nsi4
-rw-r--r--indra/newview/installers/windows/lang_en-us.nsibin11666 -> 12480 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_es.nsibin12976 -> 13790 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_fr.nsibin13492 -> 14302 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_it.nsibin12714 -> 13528 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ja.nsibin9880 -> 10698 bytes
-rw-r--r--indra/newview/installers/windows/lang_pl.nsibin12312 -> 13122 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_pt-br.nsibin13136 -> 13970 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ru.nsibin12450 -> 13264 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_tr.nsibin12360 -> 13174 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_zh.nsibin9324 -> 10144 bytes
-rw-r--r--indra/newview/licenses-mac.txt52
-rw-r--r--indra/newview/licenses-win32.txt49
-rw-r--r--indra/newview/llagent.cpp34
-rw-r--r--indra/newview/llagentcamera.cpp12
-rw-r--r--indra/newview/llagentpicksinfo.h4
-rw-r--r--indra/newview/llagentwearables.cpp21
-rw-r--r--indra/newview/llappearancemgr.cpp12
-rw-r--r--indra/newview/llappviewer.cpp236
-rw-r--r--indra/newview/llappviewer.h23
-rw-r--r--indra/newview/llaudiosourcevo.cpp36
-rw-r--r--indra/newview/llavataractions.cpp163
-rw-r--r--indra/newview/llavataractions.h28
-rw-r--r--indra/newview/llavatarlist.cpp108
-rw-r--r--indra/newview/llavatarlist.h26
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp254
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h21
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp28
-rw-r--r--indra/newview/llcallingcard.cpp4
-rw-r--r--indra/newview/llchatbar.cpp2
-rw-r--r--indra/newview/llchathistory.cpp69
-rw-r--r--indra/newview/llcolorswatch.cpp18
-rw-r--r--indra/newview/llcontrolavatar.cpp5
-rw-r--r--indra/newview/llcontrolavatar.h1
-rw-r--r--indra/newview/llconversationloglist.cpp3
-rw-r--r--indra/newview/llconversationmodel.cpp1
-rw-r--r--indra/newview/llconversationview.cpp47
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp7
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.h1
-rw-r--r--indra/newview/lldrawable.cpp7
-rw-r--r--indra/newview/lldrawable.h1
-rw-r--r--indra/newview/lldrawpool.cpp24
-rw-r--r--indra/newview/lldrawpool.h163
-rw-r--r--indra/newview/lldrawpoolalpha.cpp359
-rw-r--r--indra/newview/lldrawpoolalpha.h15
-rw-r--r--indra/newview/lldrawpoolavatar.cpp8
-rw-r--r--indra/newview/lldrawpoolbump.cpp22
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp2
-rw-r--r--indra/newview/lldrawpoolpbropaque.cpp140
-rw-r--r--indra/newview/lldrawpoolpbropaque.h63
-rw-r--r--indra/newview/lldrawpoolsky.cpp5
-rw-r--r--indra/newview/lldrawpoolterrain.cpp17
-rw-r--r--indra/newview/lldrawpoolwater.cpp72
-rw-r--r--indra/newview/lldrawpoolwater.h30
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp2
-rw-r--r--indra/newview/lldynamictexture.cpp4
-rw-r--r--indra/newview/llenvironment.cpp25
-rw-r--r--indra/newview/llface.cpp237
-rw-r--r--indra/newview/llface.h4
-rw-r--r--indra/newview/llfasttimerview.cpp14
-rw-r--r--indra/newview/llfavoritesbar.cpp85
-rw-r--r--indra/newview/llfavoritesbar.h6
-rw-r--r--indra/newview/llfeaturemanager.cpp52
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp103
-rw-r--r--indra/newview/llfetchedgltfmaterial.h57
-rw-r--r--indra/newview/llfilepicker.cpp64
-rw-r--r--indra/newview/llfilepicker.h12
-rw-r--r--indra/newview/llflexibleobject.cpp8
-rw-r--r--indra/newview/llfloater360capture.cpp7
-rw-r--r--indra/newview/llfloater360capture.h1
-rw-r--r--indra/newview/llfloaterautoreplacesettings.cpp4
-rw-r--r--indra/newview/llfloateravatarpicker.cpp3
-rw-r--r--indra/newview/llfloaterbulkpermission.cpp1
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp10
-rw-r--r--indra/newview/llfloaterchatvoicevolume.cpp2
-rw-r--r--indra/newview/llfloaterclassified.cpp71
-rw-r--r--indra/newview/llfloaterclassified.h (renamed from indra/newview/llpanelme.h)45
-rw-r--r--indra/newview/llfloatercolorpicker.cpp24
-rw-r--r--indra/newview/llfloatercolorpicker.h5
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp129
-rw-r--r--indra/newview/llfloatercreatelandmark.h3
-rw-r--r--indra/newview/llfloaterdisplayname.cpp200
-rw-r--r--indra/newview/llfloaterdisplayname.h (renamed from indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl)21
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp3
-rw-r--r--indra/newview/llfloaterevent.cpp9
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp5
-rw-r--r--indra/newview/llfloatergesture.cpp2
-rw-r--r--indra/newview/llfloaterhoverheight.cpp13
-rw-r--r--indra/newview/llfloaterimcontainer.cpp19
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp7
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp14
-rw-r--r--indra/newview/llfloaterjoystick.cpp7
-rw-r--r--indra/newview/llfloaterland.cpp10
-rw-r--r--indra/newview/llfloaterland.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermap.cpp148
-rw-r--r--indra/newview/llfloatermap.h1
-rw-r--r--indra/newview/llfloatermarketplacelistings.cpp20
-rw-r--r--indra/newview/llfloatermediasettings.cpp12
-rw-r--r--indra/newview/llfloatermediasettings.h1
-rw-r--r--indra/newview/llfloatermodelpreview.cpp45
-rw-r--r--indra/newview/llfloatermodelpreview.h1
-rw-r--r--indra/newview/llfloateroutfitsnapshot.cpp1
-rw-r--r--indra/newview/llfloaterpay.cpp2
-rw-r--r--indra/newview/llfloaterperms.cpp1
-rw-r--r--indra/newview/llfloaterpreference.cpp246
-rw-r--r--indra/newview/llfloaterpreference.h6
-rw-r--r--indra/newview/llfloaterprofile.cpp170
-rw-r--r--indra/newview/llfloaterprofile.h66
-rw-r--r--indra/newview/llfloaterprofiletexture.cpp223
-rw-r--r--indra/newview/llfloaterprofiletexture.h81
-rw-r--r--indra/newview/llfloaterregioninfo.cpp15
-rw-r--r--indra/newview/llfloaterreporter.cpp55
-rw-r--r--indra/newview/llfloaterreporter.h6
-rw-r--r--indra/newview/llfloatersearch.cpp61
-rw-r--r--indra/newview/llfloatersearch.h4
-rw-r--r--indra/newview/llfloaterspellchecksettings.cpp2
-rw-r--r--indra/newview/llfloatertools.cpp945
-rw-r--r--indra/newview/llfloatertools.h20
-rw-r--r--indra/newview/llfloateruipreview.cpp4
-rw-r--r--indra/newview/llfloaterurlentry.cpp10
-rw-r--r--indra/newview/llfloatervoicevolume.cpp2
-rw-r--r--indra/newview/llfloaterwebprofile.cpp81
-rw-r--r--indra/newview/llfloaterwebprofile.h59
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterworldmap.cpp110
-rw-r--r--indra/newview/llfloaterworldmap.h9
-rw-r--r--indra/newview/llfriendcard.cpp57
-rw-r--r--indra/newview/llfriendcard.h1
-rw-r--r--indra/newview/llgesturemgr.h2
-rw-r--r--indra/newview/llglsandbox.cpp28
-rw-r--r--indra/newview/llgltfmateriallist.cpp298
-rw-r--r--indra/newview/llgltfmateriallist.h70
-rw-r--r--indra/newview/llgroupactions.cpp2
-rw-r--r--indra/newview/llgrouplist.cpp309
-rw-r--r--indra/newview/llgrouplist.h30
-rw-r--r--indra/newview/llgroupmgr.cpp4
-rw-r--r--indra/newview/llhudeffectlookat.cpp2
-rw-r--r--indra/newview/llhudeffectpointat.cpp2
-rw-r--r--indra/newview/llhudicon.cpp54
-rw-r--r--indra/newview/llhudicon.h5
-rw-r--r--indra/newview/llhudnametag.cpp2
-rw-r--r--indra/newview/llhudobject.cpp8
-rw-r--r--indra/newview/llhudtext.cpp4
-rw-r--r--indra/newview/llimview.cpp82
-rw-r--r--indra/newview/llimview.h5
-rw-r--r--indra/newview/llinspect.cpp16
-rw-r--r--indra/newview/llinspect.h2
-rw-r--r--indra/newview/llinspectavatar.cpp15
-rw-r--r--indra/newview/llinspectgroup.cpp13
-rw-r--r--indra/newview/llinspectobject.cpp57
-rw-r--r--indra/newview/llinspectremoteobject.cpp12
-rw-r--r--indra/newview/llinspecttoast.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp127
-rw-r--r--indra/newview/llinventorybridge.h11
-rw-r--r--indra/newview/llinventoryfilter.cpp12
-rw-r--r--indra/newview/llinventoryfunctions.cpp155
-rw-r--r--indra/newview/llinventoryfunctions.h4
-rw-r--r--indra/newview/llinventoryicon.cpp5
-rw-r--r--indra/newview/llinventorylistitem.cpp32
-rw-r--r--indra/newview/llinventorymodel.cpp168
-rw-r--r--indra/newview/llinventorymodel.h30
-rw-r--r--indra/newview/llinventorypanel.cpp67
-rw-r--r--indra/newview/llinventorypanel.h7
-rw-r--r--indra/newview/lllegacyatmospherics.cpp20
-rw-r--r--indra/newview/lllocalbitmaps.cpp98
-rw-r--r--indra/newview/lllocalbitmaps.h5
-rw-r--r--indra/newview/lllocalgltfmaterials.cpp628
-rw-r--r--indra/newview/lllocalgltfmaterials.h129
-rw-r--r--indra/newview/lllocationinputctrl.h2
-rw-r--r--indra/newview/lllogininstance.cpp2
-rw-r--r--indra/newview/llmaniprotate.cpp2
-rw-r--r--indra/newview/llmanipscale.cpp2
-rw-r--r--indra/newview/llmaniptranslate.cpp22
-rw-r--r--indra/newview/llmarketplacefunctions.cpp43
-rw-r--r--indra/newview/llmarketplacefunctions.h3
-rw-r--r--indra/newview/llmaterialeditor.cpp2616
-rw-r--r--indra/newview/llmaterialeditor.h291
-rw-r--r--indra/newview/llmediadataclient.cpp3
-rw-r--r--indra/newview/llmeshrepository.cpp42
-rw-r--r--indra/newview/llmeshrepository.h5
-rw-r--r--indra/newview/llmodelpreview.cpp383
-rw-r--r--indra/newview/llmodelpreview.h31
-rw-r--r--indra/newview/llmutelist.cpp2
-rw-r--r--indra/newview/llnamelistctrl.cpp19
-rw-r--r--indra/newview/llnamelistctrl.h1
-rw-r--r--indra/newview/llnavigationbar.cpp11
-rwxr-xr-xindra/newview/llnavigationbar.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llnetmap.cpp602
-rw-r--r--indra/newview/llnetmap.h54
-rw-r--r--indra/newview/lloutfitgallery.cpp3
-rw-r--r--indra/newview/llpanelavatar.cpp224
-rw-r--r--indra/newview/llpanelavatar.h183
-rw-r--r--indra/newview/llpanelblockedlist.cpp2
-rw-r--r--indra/newview/llpanelclassified.cpp625
-rw-r--r--indra/newview/llpanelclassified.h134
-rw-r--r--indra/newview/llpaneleditsky.cpp15
-rw-r--r--indra/newview/llpaneleditsky.h1
-rw-r--r--indra/newview/llpaneleditwearable.cpp4
-rw-r--r--indra/newview/llpanelexperiences.h1
-rw-r--r--indra/newview/llpanelface.cpp2371
-rw-r--r--indra/newview/llpanelface.h66
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp4
-rw-r--r--indra/newview/llpanelgroupnotices.cpp1
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp4
-rw-r--r--indra/newview/llpanellandaudio.cpp9
-rw-r--r--indra/newview/llpanellandaudio.h1
-rw-r--r--indra/newview/llpanellandmarks.cpp52
-rw-r--r--indra/newview/llpanellandmarks.h2
-rw-r--r--indra/newview/llpanellogin.cpp147
-rw-r--r--indra/newview/llpanellogin.h1
-rw-r--r--indra/newview/llpanelloginlistener.cpp2
-rw-r--r--indra/newview/llpanelmaininventory.cpp9
-rw-r--r--indra/newview/llpanelme.cpp67
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.cpp6
-rw-r--r--indra/newview/llpanelobject.cpp342
-rw-r--r--indra/newview/llpanelobject.h27
-rw-r--r--indra/newview/llpanelobjectinventory.cpp74
-rw-r--r--indra/newview/llpanelpick.cpp620
-rw-r--r--indra/newview/llpanelpick.h264
-rw-r--r--indra/newview/llpanelpicks.cpp1484
-rw-r--r--indra/newview/llpanelpicks.h315
-rw-r--r--indra/newview/llpanelplaceinfo.cpp12
-rw-r--r--indra/newview/llpanelplaceinfo.h3
-rw-r--r--indra/newview/llpanelplaces.cpp42
-rw-r--r--indra/newview/llpanelplaces.h6
-rw-r--r--indra/newview/llpanelprofile.cpp2654
-rw-r--r--indra/newview/llpanelprofile.h411
-rw-r--r--indra/newview/llpanelprofileclassifieds.cpp1513
-rw-r--r--indra/newview/llpanelprofileclassifieds.h340
-rw-r--r--indra/newview/llpanelprofilepicks.cpp883
-rw-r--r--indra/newview/llpanelprofilepicks.h248
-rw-r--r--indra/newview/llpanelvolume.cpp419
-rw-r--r--indra/newview/llpanelvolume.h16
-rw-r--r--indra/newview/llparticipantlist.cpp170
-rw-r--r--indra/newview/llparticipantlist.h4
-rw-r--r--indra/newview/llpatchvertexarray.cpp2
-rw-r--r--indra/newview/llpathfindingmanager.cpp16
-rw-r--r--indra/newview/llpathfindingmanager.h3
-rw-r--r--indra/newview/llpersistentnotificationstorage.cpp12
-rw-r--r--indra/newview/llpersistentnotificationstorage.h1
-rw-r--r--indra/newview/llphysicsshapebuilderutil.cpp13
-rw-r--r--indra/newview/llphysicsshapebuilderutil.h1
-rw-r--r--indra/newview/llplacesinventorypanel.h2
-rw-r--r--indra/newview/llpresetsmanager.cpp2
-rw-r--r--indra/newview/llpreview.h2
-rw-r--r--indra/newview/llpreviewgesture.cpp6
-rw-r--r--indra/newview/llpreviewnotecard.cpp5
-rw-r--r--indra/newview/llpreviewscript.cpp9
-rw-r--r--indra/newview/llpreviewtexture.cpp17
-rw-r--r--indra/newview/llpreviewtexture.h2
-rw-r--r--indra/newview/llrecentpeople.cpp37
-rw-r--r--indra/newview/llrecentpeople.h13
-rw-r--r--indra/newview/llreflectionmap.cpp274
-rw-r--r--indra/newview/llreflectionmap.h102
-rw-r--r--indra/newview/llreflectionmapmanager.cpp920
-rw-r--r--indra/newview/llreflectionmapmanager.h163
-rw-r--r--indra/newview/llremoteparcelrequest.cpp7
-rw-r--r--indra/newview/llscenemonitor.cpp8
-rw-r--r--indra/newview/llsceneview.cpp10
-rw-r--r--indra/newview/llsearchableui.h12
-rw-r--r--indra/newview/llselectmgr.cpp418
-rw-r--r--indra/newview/llselectmgr.h29
-rw-r--r--indra/newview/llsettingsvo.cpp71
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp7
-rw-r--r--indra/newview/llsidepaneltaskinfo.h2
-rw-r--r--indra/newview/llspatialpartition.cpp131
-rw-r--r--indra/newview/llspatialpartition.h32
-rw-r--r--indra/newview/llspeakers.cpp2
-rw-r--r--indra/newview/llspeakers.h8
-rw-r--r--indra/newview/llsprite.cpp2
-rw-r--r--indra/newview/llstartup.cpp85
-rw-r--r--indra/newview/llsurface.cpp7
-rw-r--r--indra/newview/lltexturecache.cpp3
-rw-r--r--indra/newview/lltexturectrl.cpp398
-rw-r--r--indra/newview/lltexturectrl.h40
-rw-r--r--indra/newview/lltexturefetch.cpp626
-rw-r--r--indra/newview/lltexturefetch.h24
-rw-r--r--indra/newview/lltextureview.cpp1
-rw-r--r--indra/newview/lltinygltfhelper.cpp183
-rw-r--r--indra/newview/lltinygltfhelper.h54
-rw-r--r--indra/newview/lltoastalertpanel.cpp2
-rw-r--r--indra/newview/lltooldraganddrop.cpp116
-rw-r--r--indra/newview/lltooldraganddrop.h15
-rw-r--r--indra/newview/lltoolpie.cpp3
-rw-r--r--indra/newview/lltoolplacer.cpp2
-rw-r--r--indra/newview/lltoolselect.cpp9
-rw-r--r--indra/newview/llviewerassettype.cpp1
-rw-r--r--indra/newview/llviewerassetupload.cpp123
-rw-r--r--indra/newview/llviewerassetupload.h35
-rw-r--r--indra/newview/llvieweraudio.h2
-rw-r--r--indra/newview/llviewercamera.h13
-rw-r--r--indra/newview/llviewercontrol.cpp354
-rw-r--r--indra/newview/llviewerdisplay.cpp261
-rw-r--r--indra/newview/llviewerdisplayname.cpp226
-rw-r--r--indra/newview/llviewerdisplayname.h55
-rw-r--r--indra/newview/llviewerfloaterreg.cpp15
-rw-r--r--indra/newview/llviewerfoldertype.cpp1
-rw-r--r--indra/newview/llviewerinventory.cpp33
-rw-r--r--indra/newview/llviewermedia.cpp38
-rw-r--r--indra/newview/llviewermedia.h3
-rw-r--r--indra/newview/llviewermenu.cpp460
-rw-r--r--indra/newview/llviewermenu.h5
-rw-r--r--indra/newview/llviewermenufile.cpp59
-rw-r--r--indra/newview/llviewermenufile.h12
-rw-r--r--indra/newview/llviewermessage.cpp34
-rw-r--r--indra/newview/llviewerobject.cpp357
-rw-r--r--indra/newview/llviewerobject.h40
-rw-r--r--indra/newview/llviewerobjectlist.cpp172
-rw-r--r--indra/newview/llviewerobjectlist.h8
-rw-r--r--indra/newview/llvieweroctree.cpp39
-rw-r--r--indra/newview/llvieweroctree.h17
-rw-r--r--indra/newview/llviewerparcelmgr.cpp19
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparceloverlay.cpp80
-rw-r--r--indra/newview/llviewerparceloverlay.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerregion.cpp152
-rw-r--r--indra/newview/llviewerregion.h24
-rw-r--r--indra/newview/llviewershadermgr.cpp1252
-rw-r--r--indra/newview/llviewershadermgr.h24
-rw-r--r--indra/newview/llviewerstats.cpp2
-rw-r--r--indra/newview/llviewertexteditor.cpp26
-rw-r--r--indra/newview/llviewertexteditor.h1
-rw-r--r--indra/newview/llviewertexture.cpp33
-rw-r--r--indra/newview/llviewertexture.h4
-rw-r--r--indra/newview/llviewertexturelist.cpp200
-rw-r--r--indra/newview/llviewertexturelist.h17
-rw-r--r--indra/newview/llviewerwindow.cpp260
-rw-r--r--indra/newview/llviewerwindow.h19
-rw-r--r--indra/newview/llvoavatar.cpp107
-rw-r--r--indra/newview/llvoavatar.h12
-rw-r--r--indra/newview/llvoavatarself.cpp2
-rw-r--r--indra/newview/llvocache.cpp52
-rw-r--r--indra/newview/llvograss.cpp8
-rw-r--r--indra/newview/llvograss.h1
-rw-r--r--indra/newview/llvoground.cpp2
-rw-r--r--indra/newview/llvoicechannel.cpp23
-rw-r--r--indra/newview/llvoiceclient.cpp6
-rw-r--r--indra/newview/llvoiceclient.h1
-rw-r--r--indra/newview/llvoicevisualizer.cpp2
-rw-r--r--indra/newview/llvoicevivox.cpp56
-rw-r--r--indra/newview/llvoicevivox.h2
-rw-r--r--indra/newview/llvopartgroup.cpp12
-rw-r--r--indra/newview/llvopartgroup.h1
-rw-r--r--indra/newview/llvosky.cpp14
-rw-r--r--indra/newview/llvosurfacepatch.cpp6
-rw-r--r--indra/newview/llvosurfacepatch.h1
-rw-r--r--indra/newview/llvotree.cpp6
-rw-r--r--indra/newview/llvotree.h1
-rw-r--r--indra/newview/llvovolume.cpp529
-rw-r--r--indra/newview/llvovolume.h184
-rw-r--r--indra/newview/llvowater.cpp4
-rw-r--r--indra/newview/llvowlsky.cpp4
-rw-r--r--indra/newview/llwebprofile.cpp2
-rw-r--r--indra/newview/llworld.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapview.cpp277
-rw-r--r--indra/newview/llworldmapview.h43
-rw-r--r--indra/newview/llxmlrpctransaction.cpp10
-rw-r--r--indra/newview/pipeline.cpp2067
-rw-r--r--indra/newview/pipeline.h130
-rw-r--r--indra/newview/skins/default/colors.xml28
-rw-r--r--indra/newview/skins/default/textures/default_irradiance.pngbin0 -> 48853 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Off.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Press.pngbin0 -> 224 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.pngbin0 -> 218 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.pngbin0 -> 217 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.pngbin0 -> 215 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/CopyBright.pngbin0 -> 519 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_Material.pngbin0 -> 684 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Friend_Offline.pngbin0 -> 208 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Friend_Online.pngbin0 -> 189 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.pngbin0 -> 1608 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.pngbin0 -> 1287 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.pngbin0 -> 1356 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.pngbin0 -> 1137 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.pngbin0 -> 1312 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.pngbin0 -> 1150 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/avaline_default_icon.jpgbin3951 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.pngbin0 -> 507 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.pngbin0 -> 639 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.pngbin0 -> 485 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.pngbin0 -> 609 bytes
-rw-r--r--indra/newview/skins/default/textures/map_ui_collapse_icon.pngbin0 -> 300 bytes
-rw-r--r--indra/newview/skins/default/textures/map_ui_expand_icon.pngbin0 -> 284 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml29
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image.jpgbin0 -> 104529 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image_left.pngbin271413 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image_right.pngbin366068 -> 0 bytes
-rw-r--r--indra/newview/skins/default/xui/da/panel_me.xml7
-rw-r--r--indra/newview/skins/default/xui/da/panel_region_texture.xml4
-rw-r--r--indra/newview/skins/default/xui/da/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/da/strings.xml5
-rw-r--r--indra/newview/skins/default/xui/de/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/de/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/de/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/de/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_friends.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_photo.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_status.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/de/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/de/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml25
-rw-r--r--indra/newview/skins/default/xui/en/floater_build_options.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_classified.xml (renamed from indra/newview/skins/default/xui/en/floater_picks.xml)13
-rw-r--r--indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml48
-rw-r--r--indra/newview/skins/default/xui/en/floater_create_landmark.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_display_name.xml13
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml43
-rw-r--r--indra/newview/skins/default/xui/en/floater_map.xml78
-rw-r--r--indra/newview/skins/default/xui/en/floater_material_editor.xml532
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_environments.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_perms_default.xml68
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml253
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_texture.xml208
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile.xml88
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile_permissions.xml76
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile_texture.xml88
-rw-r--r--indra/newview/skins/default/xui/en/floater_report_abuse.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_settings_picker.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_ctrl.xml16
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml250
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml93
-rw-r--r--indra/newview/skins/default/xui/en/inspect_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/main_view.xml15
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml23
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_icon.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_self.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_conversation.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_color.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_features.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_light.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_object.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_size.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_gesture_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_im_conversation.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml554
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_mini_map.xml120
-rw-r--r--indra/newview/skins/default/xui/en/menu_object.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_other.xml171
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_self.xml85
-rw-r--r--indra/newview/skins/default/xui/en/menu_url_agent.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml93
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml202
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml37
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml354
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml239
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml472
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_list_item_short.xml110
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml71
-rw-r--r--indra/newview/skins/default/xui/en/panel_me.xml19
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml190
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml227
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml30
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_uploads.xml25
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_classified.xml830
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_classifieds.xml142
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_firstlife.xml103
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_notes.xml65
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_pick.xml314
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_picks.xml154
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_secondlife.xml549
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_web.xml36
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml23
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml134
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml42
-rw-r--r--indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/es/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/es/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/es/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/es/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/fr/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/fr/floater_facebook.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/fr/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/fr/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_photo.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_status.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/es/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/it/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/it/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/it/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/it/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_friends.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_photo.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_status.xml10
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/ja/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/ja/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/ja/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_photo.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_status.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_options.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/pl/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/strings.xml5
-rw-r--r--indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/pt/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/pt/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/it/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml40
-rw-r--r--indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/ru/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/ru/floater_report_abuse.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/panel_edit_classified.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_photo.xml14
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_place.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_status.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/tr/floater_facebook.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/tr/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/tr/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_friends.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_photo.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_status.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/zh/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/zh/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml38
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp1
-rwxr-xr-xindra/newview/viewer_manifest.py3
-rw-r--r--indra/viewer_components/login/lllogin.cpp28
-rw-r--r--scripts/content_tools/anim_tool.py9
-rw-r--r--scripts/content_tools/skel_tool.py17
1016 files changed, 49924 insertions, 25129 deletions
diff --git a/autobuild.xml b/autobuild.xml
index d6d9488530..64e1b87d16 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -17,18 +17,6 @@
<string>SDL</string>
<key>platforms</key>
<map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>459cdc8d7c19a8025f98f61db95622ff</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/sdl_3p-update-sdl/rev/297546/arch/Linux/installer/SDL-1.2.15-linux-297546.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -59,18 +47,6 @@
<string>apr_suite</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>0c53148aa00e51c06fa246c4130915be</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/apr_3p-update-apr/rev/297252/arch/Darwin/installer/apr_suite-1.4.5.297252-darwin-297252.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -83,18 +59,6 @@
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>1aa2e5355bb9df09f9196d14a72b6705</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-apr/rev/314241/arch/Linux/installer/apr_suite-1.4.5.314241-linux-314241.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -149,42 +113,18 @@
<string>boost</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>c296845cad075250c1ae2620f175a957</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/boost_3p-update-boost/rev/297445/arch/Darwin/installer/boost-1.57-darwin-297445.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>35cc090d942b85c9126ceac9912d52d6</string>
+ <string>fedc8d63856f534b6098102e059dc548</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78585/744021/boost-1.72-darwin64-557045.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87776/805857/boost-1.72-darwin64-563847.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>f1fdb548fd6c09a083c86f3a23d7f041</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-boost/rev/317807/arch/Linux/installer/boost-1.57-linux-317807.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -202,9 +142,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>9aa4ce32df5f5e36124c990e2d77b885</string>
+ <string>6cc9fb4ca21365c4470a3e516544ba71</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78586/743982/boost-1.72-windows-557045.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87784/805850/boost-1.72-windows-563847.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -214,9 +154,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>a79511c9d8b956767ebaa405155d4238</string>
+ <string>0c526efc3f8825cd25cdf635e238fab3</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78584/743961/boost-1.72-windows64-557045.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87783/805851/boost-1.72-windows64-563847.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -291,42 +231,18 @@
<string>colladadom</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>726bc31e562752f081e95e8fcc70e405</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/colladadom_3p-update-colladadom/rev/297450/arch/Darwin/installer/colladadom-2.3.297450-darwin-297450.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>1d063cf1783e7788f17486c234adb1db</string>
+ <string>4699b8389dfb754da0393ddb5d325722</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78635/744249/colladadom-2.3.557064-darwin64-557064.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95882/856117/colladadom-2.3.569219-darwin64-569219.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>78b9a6506fb7d53da166f7a65f2278f4</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-colladadom/rev/317826/arch/Linux/installer/colladadom-2.3.317826-linux-317826.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -344,9 +260,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>e78ecf919eee01567556787c3a358d15</string>
+ <string>343e46ea49a08ad6596d3dc702d5b812</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78637/744269/colladadom-2.3.557064-windows-557064.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95883/856128/colladadom-2.3.569219-windows-569219.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -356,16 +272,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>7e63a212c8909a25236138422fe01298</string>
+ <string>de5bdfb61b31db56c5fe7d0962ad11e2</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78636/744273/colladadom-2.3.557064-windows64-557064.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95884/856129/colladadom-2.3.569219-windows64-569219.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>2.3.557064</string>
+ <string>2.3.569219</string>
</map>
<key>cubemaptoequirectangular</key>
<map>
@@ -433,42 +349,18 @@
<string>curl</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>ad0061db7188a1b9a974eb0512eeeb8d</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-curl/rev/312763/arch/Darwin/installer/curl-7.47.0.312763-darwin-312763.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>13f74f43a6363ec998569f731fd869c5</string>
+ <string>44d801e05811269d1bed7dbc75d85843</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82637/774617/curl-7.54.1.560191-darwin64-560191.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87786/805905/curl-7.54.1.563852-darwin64-563852.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>9430c08954c00736117099046694e1b1</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-curl/rev/314230/arch/Linux/installer/curl-7.47.0.314230-linux-314230.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -486,11 +378,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>0df99bd685dc3561ca8ea347b2921987</string>
+ <string>676f624d4ebdc2189caa43ef6dd8266d</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82639/774610/curl-7.54.1.560191-windows-560191.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87790/805917/curl-7.54.1.563852-windows-563852.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -500,46 +392,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>50db2a9e6b74ec4b0c38b1ea8f135735</string>
+ <string>b3db5a2cdf275c1af7758fbe2d14544a</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82638/774608/curl-7.54.1.560191-windows64-560191.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87789/805918/curl-7.54.1.563852-windows64-563852.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>7.54.1.560191</string>
- </map>
- <key>db</key>
- <map>
- <key>copyright</key>
- <string>Copyright (c) 1990, 2010 Oracle and/or its affiliates. All rights reserved.</string>
- <key>description</key>
- <string>Berkeley DB (libdb) is a programmatic toolkit that provides embedded database support for both traditional and client/server applications.</string>
- <key>license</key>
- <string>bsd</string>
- <key>license_file</key>
- <string>LICENSES/db.txt</string>
- <key>name</key>
- <string>db</string>
- <key>platforms</key>
- <map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>1cc7940e500858a9754e9a3cc3ba2237</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/db_3p-update-db/rev/295315/arch/Linux/installer/db-5.1.25-linux-295315.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
- </map>
- <key>version</key>
- <string>5.1.25</string>
+ <string>7.54.1.563852</string>
</map>
<key>dbus_glib</key>
<map>
@@ -555,18 +417,6 @@
<string>dbus_glib</string>
<key>platforms</key>
<map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>6d676abd9ad8d2883b855dbe397d9034</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-dbus-glib/rev/314266/arch/Linux/installer/dbus_glib-0.76-linux-314266.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -632,9 +482,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>2653c3627fd8687ff9e003425fd14834</string>
+ <string>439d92ec73f0500ba1671faad2bd8090</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90199/821852/dullahan-1.12.3.202111032211_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-565428.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104637/916643/dullahan-1.12.4.202209142017_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-575005.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -644,9 +494,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>b4003772562a5dd40bc112eec7cba5f5</string>
+ <string>2a7c01da15de77bc1fd1863327174d5e</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90201/821871/dullahan-1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-565428.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104638/916654/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-575005.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -656,40 +506,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>d9030d7a7390b3bda7de2adcc27e535a</string>
+ <string>d06bee9b2517fbb09ba1a65e6d675361</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90200/821876/dullahan-1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-565428.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104639/916659/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-575005.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
- </map>
- <key>elfio</key>
- <map>
- <key>license</key>
- <string>lgpl</string>
- <key>license_file</key>
- <string>LICENSES/elfio.txt</string>
- <key>name</key>
- <string>elfio</string>
- <key>platforms</key>
- <map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>031e6315a5c0829c9b9a2ec18aeb7ae3</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-elfio/rev/222074/arch/Linux/installer/elfio-1.0.3-linux-20110225.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
- </map>
+ <string>1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
</map>
<key>expat</key>
<map>
@@ -705,18 +531,6 @@
<string>expat</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>452d1910ef853329cd59858e6c5b2c48</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/expat_3p-update-expat/rev/297014/arch/Darwin/installer/expat-2.0.1.297014-darwin-297014.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -729,18 +543,6 @@
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>387c90b9bb5ec412587fbe7a56261dd1</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-expat/rev/314211/arch/Linux/installer/expat-2.1.1.314211-linux-314211.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -800,25 +602,13 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>c36808a58384a52672d81593de61f7ff</string>
+ <string>2c619c1bef969dc42b4f44a4651b314e</string>
<key>url</key>
- <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89681/818422/fmodstudio-2.02.03.565082-darwin64-565082.tar.bz2</string>
+ <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98369/869141/fmodstudio-2.02.06.570913-darwin64-570913.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>24b86630ccdfb5b3221f90ca7a9704f6</string>
- <key>url</key>
- <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89682/818423/fmodstudio-2.02.03.565082-linux-565082.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -836,9 +626,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>96853d91ce4da14e14ea322122629551</string>
+ <string>875ccd8c1feec8ff03438d453371044b</string>
<key>url</key>
- <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89683/818438/fmodstudio-2.02.03.565082-windows-565082.tar.bz2</string>
+ <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98371/869153/fmodstudio-2.02.06.570913-windows-570913.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -848,16 +638,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>58d0cc28a1d90bacefbda48fcd8d379c</string>
+ <string>5e402f4828741bce942e2ced318cd02a</string>
<key>url</key>
- <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89684/818439/fmodstudio-2.02.03.565082-windows64-565082.tar.bz2</string>
+ <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98372/869154/fmodstudio-2.02.06.570913-windows64-570913.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>2.02.03.565082</string>
+ <string>2.02.06.570913</string>
</map>
<key>fontconfig</key>
<map>
@@ -873,18 +663,6 @@
<string>fontconfig</string>
<key>platforms</key>
<map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>a20a3d0ab7fc3401bc2ca81e9309f630</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-fontconfig/rev/314281/arch/Linux/installer/fontconfig-2.11.0-linux-314281.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -915,42 +693,18 @@
<string>freetype</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>83618d16d974eb0af93926a10ac13297</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/freetype_3p-update-freetype/rev/297053/arch/Darwin/installer/freetype-2.4.4.297053-darwin-297053.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>3a478d6c8a10d49d9161ef864394b03c</string>
+ <string>8865739d8e530199dacb3c3042c1bc01</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78592/744013/freetype-2.4.4.557047-darwin64-557047.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87777/805782/freetype-2.4.4.563848-darwin64-563848.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>1b401394106cedc86926bd488f5aa45e</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-freetype/rev/314215/arch/Linux/installer/freetype-2.4.4.314215-linux-314215.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -968,9 +722,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>7ee200d6b5fa282c7f973ade5615aa86</string>
+ <string>c0b3601e997553931cadc7d7ee94168b</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78594/744011/freetype-2.4.4.557047-windows-557047.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87779/805814/freetype-2.4.4.563848-windows-563848.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -980,16 +734,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>69307aaba16ac71531c9c4d930ace993</string>
+ <string>e98e1e088cdcd20442e05e9abecdadf9</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78593/744010/freetype-2.4.4.557047-windows64-557047.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87778/805815/freetype-2.4.4.563848-windows64-563848.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>2.4.4.557047</string>
+ <string>2.4.4.563848</string>
</map>
<key>glext</key>
<map>
@@ -1005,65 +759,17 @@
<string>glext</string>
<key>platforms</key>
<map>
- <key>darwin64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>1bd3214ac23474ea4c869e386970a1be</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54835/510029/glext-68-darwin64-538965.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin64</string>
- </map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>baf1fd13e1fe6aef586200fc87a70f53</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-glext/rev/314200/arch/Linux/installer/glext-68-linux-314200.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
- <key>linux64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>5f3c9d61b620f949b199ebd8885218ed</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-glext/rev/314200/arch/Linux/installer/glext-68-linux64-314200.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux64</string>
- </map>
- <key>windows</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>6a311615bce59b01cf73ee65012a9b38</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54951/511711/glext-68-windows-538965.tar.bz2</string>
- </map>
- <key>name</key>
- <string>windows</string>
- </map>
- <key>windows64</key>
+ <key>common</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>daf619dab1cf7518af6532b18800c4b0</string>
+ <string>4f8dc85863fec36e8d872c31f4abcd05</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54924/511490/glext-68-windows64-538965.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101480/892402/glext-68-common-572829.tar.bz2</string>
</map>
<key>name</key>
- <string>windows64</string>
+ <string>common</string>
</map>
</map>
<key>version</key>
@@ -1113,42 +819,18 @@
<string>googlemock</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>022649e284163b8ee23e3c9a81302fa7</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/googlemock_3p-update-googlemock/rev/297460/arch/Darwin/installer/googlemock-1.7.0.297460-darwin-297460.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>19e925604bc1a91efb4b130e1edd8bf2</string>
+ <string>11d0794582e91a57f6524ad345f2399d</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78620/744140/googlemock-1.7.0.557057-darwin64-557057.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87791/805924/googlemock-1.7.0.563853-darwin64-563853.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>ad51f68702f25ba245fff312c50c8876</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-googlemock/rev/317828/arch/Linux/installer/googlemock-1.7.0.317828-linux-317828.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1166,9 +848,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>eed7b41d0d1f41b24f315349ef78c728</string>
+ <string>7d267050970ec6e28749178597bc8af0</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78622/744148/googlemock-1.7.0.557057-windows-557057.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87793/805930/googlemock-1.7.0.563853-windows-563853.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1178,16 +860,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>a6ad6fe722d2fe4e8137495af3f374c9</string>
+ <string>27638c692f0ec6121e54bf75f2d45e49</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78621/744152/googlemock-1.7.0.557057-windows64-557057.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87792/805936/googlemock-1.7.0.563853-windows64-563853.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>1.7.0.557057</string>
+ <string>1.7.0.563853</string>
</map>
<key>gstreamer</key>
<map>
@@ -1201,18 +883,6 @@
<string>gstreamer</string>
<key>platforms</key>
<map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>5017b3e95d2c6f47bb111c3f9c075522</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gstreamer/rev/314267/arch/Linux/installer/gstreamer-0.10.6.314267-linux-314267.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1241,18 +911,6 @@
<string>gtk-atk-pango-glib</string>
<key>platforms</key>
<map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>a6431df705526501684d9050e04bfa5b</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gtk-atk-pango-glib/rev/314220/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux-314220.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1283,18 +941,6 @@
<string>havok-source</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>5c5b4820999ae9e398801d6a46f45897</string>
- <key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/297312/arch/Darwin/installer/havok_source-2012.1-darwin-297312.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -1307,18 +953,6 @@
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>03c1c5f7c3e93e905f635ca22b607494</string>
- <key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/p64_3p-havok-source/rev/314226/arch/Linux/installer/havok_source-2012.1-2-linux-314226.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1425,18 +1059,6 @@
<string>jpeglib</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>4d7658997fd0f93a9c55e40e40b1b0e5</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/jpeglib_3p-update-jpeglib/rev/296854/arch/Darwin/installer/jpeglib-8c.296854-darwin-296854.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -1449,18 +1071,6 @@
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>32560d3200da72fea2922371fcef25f5</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-jpeglib/rev/314202/arch/Linux/installer/jpeglib-8c.314202-linux-314202.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1515,18 +1125,6 @@
<string>jsoncpp</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>b25a4f480e07c670ffef00c3da578f87</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/jsoncpp_3p-update-jsoncpp/rev/297281/arch/Darwin/installer/jsoncpp-0.5.0.297281-darwin-297281.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -1539,18 +1137,6 @@
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>9d5d9fec28cbbb1651b95728173f8af7</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-jsoncpp/rev/314229/arch/Linux/installer/jsoncpp-0.5.0.314229-linux-314229.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1605,18 +1191,6 @@
<string>kdu</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>3855bd40f950e3c22739ae8f3ee2afc9</string>
- <key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15258/98444/kdu-7.10.4.513518-darwin-513518.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -1629,18 +1203,6 @@
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>43d7a6a69a54534a736f132e9c81795b</string>
- <key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15255/98451/kdu-7.10.4.513518-linux-513518.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1695,18 +1257,6 @@
<string>libhunspell</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>05eda16106df26a211f8bdd874d1fca5</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/hunspell_3p-update-hunspell/rev/296916/arch/Darwin/installer/libhunspell-1.3.2.296916-darwin-296916.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -1719,18 +1269,6 @@
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>0d8009c3b6c1eb510593476dd1d821b5</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-hunspell/rev/314217/arch/Linux/installer/libhunspell-1.3.2.314217-linux-314217.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1785,18 +1323,6 @@
<string>libndofdev</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>a01b411433dbf8a4b481de9e76d9a652</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libndofdev_3p-update-libndofdev/rev/297264/arch/Darwin/installer/libndofdev-0.1.297264-darwin-297264.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -1851,42 +1377,18 @@
<string>libpng</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>14cb5c8686a472e9e60179e46cd196f7</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libpng_3p-update-libpng/rev/297708/arch/Darwin/installer/libpng-1.6.8.297708-darwin-297708.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>2a41acc3116ce19a443873216cb882ad</string>
+ <string>c1c9e32e21f3c34d91ed045b2ca91f24</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78587/743948/libpng-1.6.8.557046-darwin64-557046.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87781/805801/libpng-1.6.8.563850-darwin64-563850.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>0758f3cb4c02ebab61854b811b0894e9</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libpng/rev/314214/arch/Linux/installer/libpng-1.6.8.314214-linux-314214.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1904,9 +1406,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>b935b440947f63c69700bdcf5095a8e1</string>
+ <string>642e9cf95c8ccd0eb34f6d7a40df585a</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78591/743970/libpng-1.6.8.557046-windows-557046.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87782/805831/libpng-1.6.8.563850-windows-563850.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1916,16 +1418,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>d1cc8354ac4e877eefedf16b1be3aac6</string>
+ <string>ce46aa0f171d97626c4a3940347cecd7</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78589/743991/libpng-1.6.8.557046-windows64-557046.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87780/805832/libpng-1.6.8.563850-windows64-563850.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>1.6.8.557046</string>
+ <string>1.6.8.563850</string>
</map>
<key>libuuid</key>
<map>
@@ -1941,18 +1443,6 @@
<string>libuuid</string>
<key>platforms</key>
<map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>a2eaf9515cd129f3e21a08e92689006b</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libuuid/rev/314269/arch/Linux/installer/libuuid-1.6.2-linux-314269.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -1983,42 +1473,18 @@
<string>libxml2</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>9303f0dd174129e297eca6cc2eb1ab3f</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libxml_3p-update-libxml/rev/297050/arch/Darwin/installer/libxml2-2.9.1.297050-darwin-297050.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>6677173bbbb0ea32369b5e9b6c9aa641</string>
+ <string>6f37dd6c4a5174f358b6cc5d953f121b</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78631/744225/libxml2-2.9.4.557062-darwin64-557062.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87768/805766/libxml2-2.9.4.563845-darwin64-563845.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>6954173a141d928f2614076577d952de</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libxml/rev/314197/arch/Linux/installer/libxml2-2.9.1.314197-linux-314197.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -2036,9 +1502,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>ad6a596fbf0e83a21d95762da78437bc</string>
+ <string>fd85d3aa13fbdfd1f1ace587e95ef151</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78633/744239/libxml2-2.9.4.557062-windows-557062.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87773/805797/libxml2-2.9.4.563845-windows-563845.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -2048,16 +1514,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>6b5bb230684ecf28386d7c91c47bb6e1</string>
+ <string>d231d36c3b8942e0259aa2d9fcaa3b7e</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78634/744240/libxml2-2.9.4.557062-windows64-557062.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87772/805795/libxml2-2.9.4.563845-windows64-563845.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>2.9.4.557062</string>
+ <string>2.9.4.563845</string>
</map>
<key>llappearance_utility</key>
<map>
@@ -2370,6 +1836,118 @@
<key>version</key>
<string>0.16.561408</string>
</map>
+ <key>mikktspace</key>
+ <map>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-mikktspace</string>
+ <key>copyright</key>
+ <string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
+ <key>description</key>
+ <string>Mikktspace Tangent Generator</string>
+ <key>license</key>
+ <string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
+ <key>license_file</key>
+ <string>mikktspace.txt</string>
+ <key>name</key>
+ <string>mikktspace</string>
+ <key>platforms</key>
+ <map>
+ <key>darwin64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>b48b7ac0792d3ea8f087d99d9e4a29d8</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104415/914944/mikktspace-1-darwin64-574859.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin64</string>
+ </map>
+ <key>windows</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>0a016b9c0c1e2c0b557e0124094da6c5</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104407/914918/mikktspace-1-windows-574859.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows</string>
+ </map>
+ <key>windows64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>02e9e5b6fe6788f4d2babb83ec544843</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104406/914909/mikktspace-1-windows64-574859.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows64</string>
+ </map>
+ </map>
+ <key>version</key>
+ <string>1</string>
+ </map>
+ <key>minizip-ng</key>
+ <map>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-minizip-ng</string>
+ <key>copyright</key>
+ <string>This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler</string>
+ <key>description</key>
+ <string>minizip-ng is a zip manipulation library. Based on work of Gilles Vollant.</string>
+ <key>license</key>
+ <string>minizip-ng</string>
+ <key>license_file</key>
+ <string>LICENSES/minizip-ng.txt</string>
+ <key>name</key>
+ <string>minizip-ng</string>
+ <key>platforms</key>
+ <map>
+ <key>darwin64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>843587a078102d86d90054d03354684d</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95876/856095/minizip_ng-3.0.2.569217-darwin64-569217.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin64</string>
+ </map>
+ <key>windows</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>26dc254f443ca9c5509547d7fbd9d8e5</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95878/856107/minizip_ng-3.0.2.569217-windows-569217.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows</string>
+ </map>
+ <key>windows64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>e9241fa325f4014995b62193321e7a1c</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95877/856106/minizip_ng-3.0.2.569217-windows64-569217.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows64</string>
+ </map>
+ </map>
+ <key>version</key>
+ <string>3.0.2.569217</string>
+ </map>
<key>nghttp2</key>
<map>
<key>copyright</key>
@@ -2397,18 +1975,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>079c1a1bdb3ce1cda8ce3d7f75eeced3</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/9258/41585/nghttp2-1.25.0.509246-linux-509246.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -2507,18 +2073,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>ogg_vorbis</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>07fca1531a27915f642a5c1d95008d54</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/oggvorbis_3p-update-oggvorbis/rev/296878/arch/Darwin/installer/ogg_vorbis-1.2.2-1.3.2.296878-darwin-296878.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -2531,18 +2085,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>5c9d94dce4551b19790057766ff939ea</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-oggvorbis/rev/314224/arch/Linux/installer/ogg_vorbis-1.2.2-1.3.2.314224-linux-314224.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -2595,21 +2137,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>LICENSES/libndofdev.txt</string>
<key>name</key>
<string>open-libndofdev</string>
- <key>platforms</key>
- <map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>b1245d467d5914a266efa16afeb55406</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libndofdev_3p-update-libndofdev/rev/297553/arch/Linux/installer/open_libndofdev-0.3-linux-297553.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
- </map>
<key>version</key>
<string>0.3</string>
</map>
@@ -2627,20 +2154,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>openal</string>
<key>platforms</key>
<map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>24b91eda3831a51c7774644016c4cb09</string>
- <key>hash_algorithm</key>
- <string>md5</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/Linux/installer/openal-1.12.854-1.1.0.314223-linux-314223.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -2697,18 +2210,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>openjpeg</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>2adb5b8bd2493d576c5d02b992d8f819</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openjpeg_3p-update-openjpeg/rev/297018/arch/Darwin/installer/openjpeg-1.4.297018-darwin-297018.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -2721,18 +2222,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>e82317482647559d46a818ba48e9423a</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openjpeg/rev/314205/arch/Linux/installer/openjpeg-2.0.0.314205-linux-314205.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -2787,42 +2276,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>openssl</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>0a77d56769e6075957f614be6575423e</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openssl_3p-update-openssl/rev/297168/arch/Darwin/installer/openssl-1.0.1h.297168-darwin-297168.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>5503e4928bcdb0a29685b3242c4a409b</string>
+ <string>142d0ad85d0ee4fbb673c9f9e414fbdd</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82619/774464/openssl-1.1.1l.560177-darwin64-560177.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87769/805772/openssl-1.1.1l.563846-darwin64-563846.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>f46a601d60b7dbcfde32afc0cb64453e</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openssl/rev/314227/arch/Linux/installer/openssl-1.0.1h.314227-linux-314227.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -2840,9 +2305,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>d2153f20dc2d35c609b876a9f019a748</string>
+ <string>55bd833166d03f1467e2c7f24fa9143e</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82623/774521/openssl-1.1.1l.560177-windows-560177.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87775/805841/openssl-1.1.1l.563846-windows-563846.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -2852,16 +2317,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>f40b8622ba38084b0962e273988d748f</string>
+ <string>6fefc60f68882fc6b246521b696497ab</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82624/774520/openssl-1.1.1l.560177-windows64-560177.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87774/805833/openssl-1.1.1l.563846-windows64-563846.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>1.1.1l.560177</string>
+ <string>1.1.1l.563846</string>
</map>
<key>pcre</key>
<map>
@@ -2877,18 +2342,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>pcre</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>6d2b38897f1adf354b299345d5fc759b</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/pcre_3p-update-pcre/rev/297155/arch/Darwin/installer/pcre-8.35.-darwin-297155.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -2901,18 +2354,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>24a119b18e63017ad932ad54df8161bc</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-pcre/rev/314136/arch/Linux/installer/pcre-8.35.314136-linux-314136.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -2935,7 +2376,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55041/512002/pcre-8.35.538986-windows-538986.tar.bz2</string>
</map>
<key>name</key>
- <string>linux</string>
+ <string>windows</string>
</map>
<key>windows64</key>
<map>
@@ -2967,42 +2408,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>slvoice</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>511a9c3fd4b6c76a8a737d06bba1c291</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/oz-426-slvoice/rev/330003/arch/Darwin/installer/slvoice-4.9.0002.27586.330003-darwin-330003.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>6ce3cbaed968a69fb7a2cca80220874d</string>
+ <string>b583668b28fde0490e6953f10e93e4ab</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80380/758537/slvoice-4.10.0000.32327.5fc3fe7c.558436-darwin64-558436.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98681/871545/slvoice-4.10.0000.32327.5fc3fe7c.571099-darwin64-571099.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>785c86999b56e1838cefb430f674cba7</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/oz-426-slvoice/rev/330003/arch/Linux/installer/slvoice-3.2.0002.10426.330003-linux-330003.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -3020,9 +2437,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>2eb38c5eff4d0f18fbb89d0c30c4f0a4</string>
+ <string>6e0ed41653955afe8eeb8945776cf07b</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80382/758550/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows-558436.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98683/871560/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows-571099.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -3032,16 +2449,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>9ee8f3cbc5369c598a998c61961ed16d</string>
+ <string>c39735851fd05c194d0be09b8f9e8cb7</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80381/758551/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows64-558436.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98682/871552/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows64-571099.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>4.10.0000.32327.5fc3fe7c.558436</string>
+ <string>4.10.0000.32327.5fc3fe7c.571099</string>
</map>
<key>threejs</key>
<map>
@@ -3095,6 +2512,42 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>version</key>
<string>0.132.2</string>
</map>
+ <key>tinygltf</key>
+ <map>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-tinygltf</string>
+ <key>copyright</key>
+ <string>// Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many contributors.</string>
+ <key>description</key>
+ <string>tinygltf import library</string>
+ <key>license</key>
+ <string>MIT</string>
+ <key>license_file</key>
+ <string>LICENSES/tinygltf_license.txt</string>
+ <key>name</key>
+ <string>tinygltf</string>
+ <key>platforms</key>
+ <map>
+ <key>common</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>4dad1c0948141e1667c01a3ee755e4dc</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105849/926137/tinygltf-v2.5.0-common-575729.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>common</string>
+ </map>
+ </map>
+ <key>source</key>
+ <string>https://bitbucket.org/lindenlab/3p-tinygltf</string>
+ <key>source_type</key>
+ <string>git</string>
+ <key>version</key>
+ <string>v2.5.0</string>
+ </map>
<key>tracy</key>
<map>
<key>canonical_repo</key>
@@ -3203,18 +2656,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>uriparser</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>22608adaf54e8ddc9182a719ba6e2b32</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/uriparser_3p-update-uriparser/rev/299435/arch/Darwin/installer/uriparser-0.8.0.1-darwin-299435.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
@@ -3227,18 +2668,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>dddfc8dea540801f93ba0382cb1e3685</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/uriparser_3p-update-uriparser/rev/299435/arch/Linux/installer/uriparser-0.8.0.1-linux-299435.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -3305,18 +2734,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>8c7f32f85850248809ae811ba8e47d81</string>
- <key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3428/8686/viewer_manager-1.0-linux-503417.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>windows</key>
<map>
<key>archive</key>
@@ -3361,18 +2778,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>2f410640df3f9812d1abff02a414cfa8</string>
- <key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-vlc-bin/rev/315283/arch/Linux/vlc_bin-2.2.3-linux-201606011750-r10.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>windows</key>
<map>
<key>archive</key>
@@ -3401,55 +2806,87 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>version</key>
<string>3.0.16.565299</string>
</map>
- <key>xmlrpc-epi</key>
+ <key>vulkan_gltf</key>
<map>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr</string>
<key>copyright</key>
- <string>Copyright: (C) 2000 Epinions, Inc.</string>
+ <string>Copyright (c) 2018 Sascha Willems</string>
<key>description</key>
- <string>XMLRPC Library</string>
+ <string>Vulkan GLTF Sample Implementation</string>
<key>license</key>
- <string>xmlrpc-epi</string>
+ <string>Copyright (c) 2018 Sascha Willems</string>
<key>license_file</key>
- <string>LICENSES/xmlrpc-epi.txt</string>
+ <string>LICENSES/vulkan_gltf.txt</string>
<key>name</key>
- <string>xmlrpc-epi</string>
+ <string>vulkan_gltf</string>
<key>platforms</key>
<map>
- <key>darwin</key>
+ <key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>ffd3aab8e0c0ff6dadbce49ca2809078</string>
+ <string>8cff2060843db3db788511ee34a8e8cc</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/xmlrpc-emi_3p-update-xmlrpc-epi/rev/297075/arch/Darwin/installer/xmlrpc_epi-0.54.1.297075-darwin-297075.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2</string>
</map>
<key>name</key>
- <string>darwin</string>
+ <string>darwin64</string>
</map>
- <key>darwin64</key>
+ <key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>922a0dea32266897ed1911200438e1e1</string>
+ <string>58eea384be49ba756ce9c5e66669540b</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76372/727426/xmlrpc_epi-0.54.1.555529-darwin64-555529.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2</string>
</map>
<key>name</key>
- <string>darwin64</string>
+ <string>windows</string>
</map>
- <key>linux</key>
+ <key>windows64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>b63f828e798287d475991134cdcfbca3</string>
+ <string>79b6a11622c2f83cfc2b7cd1fafb867b</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-xmlrpc-epi/rev/314240/arch/Linux/installer/xmlrpc_epi-0.54.1.314240-linux-314240.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2</string>
</map>
<key>name</key>
- <string>linux</string>
+ <string>windows64</string>
+ </map>
+ </map>
+ <key>version</key>
+ <string>1</string>
+ </map>
+ <key>xmlrpc-epi</key>
+ <map>
+ <key>copyright</key>
+ <string>Copyright: (C) 2000 Epinions, Inc.</string>
+ <key>description</key>
+ <string>XMLRPC Library</string>
+ <key>license</key>
+ <string>xmlrpc-epi</string>
+ <key>license_file</key>
+ <string>LICENSES/xmlrpc-epi.txt</string>
+ <key>name</key>
+ <string>xmlrpc-epi</string>
+ <key>platforms</key>
+ <map>
+ <key>darwin64</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>922a0dea32266897ed1911200438e1e1</string>
+ <key>url</key>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76372/727426/xmlrpc_epi-0.54.1.555529-darwin64-555529.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin64</string>
</map>
<key>linux64</key>
<map>
@@ -3491,58 +2928,34 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>version</key>
<string>0.54.1.555529</string>
</map>
- <key>zlib</key>
+ <key>zlib-ng</key>
<map>
+ <key>canonical_repo</key>
+ <string>https://bitbucket.org/lindenlab/3p-zlib-ng</string>
<key>copyright</key>
<string>Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler</string>
<key>description</key>
- <string>Zlib Data Compression Library</string>
+ <string>zlib data compression library for the next generation systems</string>
<key>license</key>
- <string>zlib</string>
+ <string>zlib-ng</string>
<key>license_file</key>
- <string>LICENSES/zlib.txt</string>
+ <string>LICENSES/zlib-ng.txt</string>
<key>name</key>
- <string>zlib</string>
+ <string>zlib-ng</string>
<key>platforms</key>
<map>
- <key>darwin</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>1a79eeac199c2d94e4ae4e5d0194e25f</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/zlib_3p-update-zlib/rev/296881/arch/Darwin/installer/zlib-1.2.8.296881-darwin-296881.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin</string>
- </map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
- <string>9181bc8229f1a8e480d2a40a2744ec28</string>
+ <string>bf306e38bf81c6095e0967bdef6a2445</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78578/743913/zlib-1.2.11.557041-darwin64-557041.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87759/805718/zlib_ng-2.0.5.563838-darwin64-563838.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>98a8c775c581ca80bb559e8b4e8eaae7</string>
- <key>hash_algorithm</key>
- <string>md5</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-zlib/rev/314131/arch/Linux/installer/zlib-1.2.8.314131-linux-314131.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>linux64</key>
<map>
<key>archive</key>
@@ -3560,9 +2973,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>8308cbd2ea0fe290541698b0f63482e2</string>
+ <string>8ffce5bd00e3d5afa8cb39b855237c4a</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78579/743926/zlib-1.2.11.557041-windows-557041.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87761/805730/zlib_ng-2.0.5.563838-windows-563838.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -3572,16 +2985,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>36bdc34f67d3ad3c57125dc1b16a3129</string>
+ <string>bd103a9129e57f7ea35886bc7750f8a6</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78577/743920/zlib-1.2.11.557041-windows64-557041.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87760/805729/zlib_ng-2.0.5.563838-windows64-563838.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>1.2.11.557041</string>
+ <string>2.0.5.563838</string>
</map>
</map>
<key>package_description</key>
@@ -3810,126 +3223,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>name</key>
<string>darwin64</string>
</map>
- <key>linux</key>
- <map>
- <key>build_directory</key>
- <string>build-linux-i686</string>
- <key>configurations</key>
- <map>
- <key>RelWithDebInfo</key>
- <map>
- <key>build</key>
- <map>
- <key>command</key>
- <string>make</string>
- <key>options</key>
- <array>
- <string>-j</string>
- <string>12</string>
- </array>
- </map>
- <key>configure</key>
- <map>
- <key>arguments</key>
- <array>
- <string>../indra</string>
- </array>
- <key>options</key>
- <array>
- <string>-G</string>
- <string>Unix Makefiles</string>
- </array>
- </map>
- <key>default</key>
- <string>True</string>
- <key>name</key>
- <string>RelWithDebInfo</string>
- </map>
- <key>RelWithDebInfoOS</key>
- <map>
- <key>build</key>
- <map>
- <key>command</key>
- <string>make</string>
- <key>options</key>
- <array>
- <string>-j</string>
- <string>7</string>
- </array>
- </map>
- <key>configure</key>
- <map>
- <key>options</key>
- <array>
- <string>-G</string>
- <string>Unix Makefiles</string>
- </array>
- </map>
- <key>name</key>
- <string>RelWithDebInfoOS</string>
- </map>
- <key>Release</key>
- <map>
- <key>build</key>
- <map>
- <key>command</key>
- <string>make</string>
- <key>options</key>
- <array>
- <string>-j</string>
- <string>12</string>
- </array>
- </map>
- <key>configure</key>
- <map>
- <key>arguments</key>
- <array>
- <string>../indra</string>
- </array>
- <key>options</key>
- <array>
- <string>-G</string>
- <string>Unix Makefiles</string>
- </array>
- </map>
- <key>name</key>
- <string>Release</string>
- </map>
- <key>ReleaseOS</key>
- <map>
- <key>build</key>
- <map>
- <key>command</key>
- <string>make</string>
- <key>options</key>
- <array>
- <string>-j</string>
- <string>7</string>
- </array>
- </map>
- <key>configure</key>
- <map>
- <key>options</key>
- <array>
- <string>-G</string>
- <string>Unix Makefiles</string>
- </array>
- </map>
- <key>name</key>
- <string>ReleaseOS</string>
- </map>
- <key>default</key>
- <map>
- <key>build</key>
- <map>
- </map>
- <key>name</key>
- <string>default</string>
- </map>
- </map>
- <key>name</key>
- <string>linux</string>
- </map>
<key>windows</key>
<map>
<key>build_directory</key>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 0acf92b189..9368781c9a 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -223,6 +223,7 @@ Ansariel Hiller
MAINT-8723
SL-10385
SL-10891
+ SL-10675
SL-13364
SL-13858
SL-13697
@@ -235,6 +236,7 @@ Ansariel Hiller
SL-15226
SL-15227
SL-15398
+ SL-18432
Aralara Rajal
Arare Chantilly
CHUIBUG-191
@@ -400,6 +402,7 @@ Cinder Roxley
STORM-2127
STORM-2144
SL-3404
+ SL-17634
Clara Young
Coaldust Numbers
VWR-1095
@@ -820,6 +823,7 @@ Jonathan Yap
Kadah Coba
STORM-1060
STORM-1843
+ SL-10675
Jondan Lundquist
Joosten Briebers
MAINT-7074
@@ -1108,16 +1112,19 @@ Nicky Dasmijn
STORM-1937
OPEN-187
SL-15234
- STORM-2010
+ STORM-2010
STORM-2082
MAINT-6665
SL-10291
SL-10293
SL-11061
- SL-11072
+ SL-11072
SL-13141
SL-13642
+ SL-14541
SL-16438
+ SL-17218
+ SL-17585
Nicky Perian
OPEN-1
STORM-1087
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index f93a09d232..68f6e962ef 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -13,7 +13,6 @@ project(${ROOT_PROJECT_NAME})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(Variables)
-include(bugsplat)
include(BuildVersion)
set(LEGACY_STDIO_LIBS)
@@ -73,6 +72,12 @@ if (LINUX)
include(LLAppearanceUtility)
add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
endif (INSTALL_PROPRIETARY)
+ add_dependencies(viewer linux-crash-logger-strip-target)
+elseif (WINDOWS)
+ # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
+ if (EXISTS ${VIEWER_DIR}win_setup)
+ add_subdirectory(${VIEWER_DIR}win_setup)
+ endif (EXISTS ${VIEWER_DIR}win_setup)
endif (LINUX)
if (WINDOWS)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index bb5dd8f847..d81d3ac1f0 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -223,7 +223,6 @@ if (USESYSTEMLIBS)
else (USESYSTEMLIBS)
set(${ARCH}_linux_INCLUDES
- ELFIO
atk-1.0
glib-2.0
gstreamer-0.10
@@ -233,3 +232,4 @@ else (USESYSTEMLIBS)
endif (USESYSTEMLIBS)
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index 1a01671002..9b64bc6160 100644
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -1,4 +1,3 @@
-include(BerkeleyDB)
include(Linking)
include(Prebuilt)
@@ -49,7 +48,7 @@ else (USESYSTEMLIBS)
set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)
if (LINUX)
- list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
- list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)
+ list(APPEND APRUTIL_LIBRARIES uuid)
+ list(APPEND APRUTIL_LIBRARIES rt)
endif (LINUX)
endif (USESYSTEMLIBS)
diff --git a/indra/cmake/BerkeleyDB.cmake b/indra/cmake/BerkeleyDB.cmake
deleted file mode 100644
index ee670ac650..0000000000
--- a/indra/cmake/BerkeleyDB.cmake
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-set(DB_FIND_QUIETLY ON)
-set(DB_FIND_REQUIRED ON)
-
-if (USESYSTEMLIBS)
- include(FindBerkeleyDB)
-else (USESYSTEMLIBS)
- if (LINUX)
- # Need to add dependency pthread explicitely to support ld.gold.
- use_prebuilt_binary(db)
- set(DB_LIBRARIES db-5.1 pthread)
- else (LINUX)
- set(DB_LIBRARIES db-4.2)
- endif (LINUX)
- set(DB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
-endif (USESYSTEMLIBS)
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake
index 26604d4913..e79dc33245 100644
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -24,57 +24,30 @@ else (USESYSTEMLIBS)
set(addrsfx "-x${ADDRESS_SIZE}")
if (WINDOWS)
- if(MSVC80)
- # This should be obsolete at this point
- set(BOOST_VERSION "1.55")
- set(BOOST_CONTEXT_LIBRARY
- optimized libboost_context-vc80-mt-${BOOST_VERSION}
- debug libboost_context-vc80-mt-gd-${BOOST_VERSION})
- set(BOOST_FILESYSTEM_LIBRARY
- optimized libboost_filesystem-vc80-mt-${BOOST_VERSION}
- debug libboost_filesystem-vc80-mt-gd-${BOOST_VERSION})
- set(BOOST_PROGRAM_OPTIONS_LIBRARY
- optimized libboost_program_options-vc80-mt-${BOOST_VERSION}
- debug libboost_program_options-vc80-mt-gd-${BOOST_VERSION})
- set(BOOST_REGEX_LIBRARY
- optimized libboost_regex-vc80-mt-${BOOST_VERSION}
- debug libboost_regex-vc80-mt-gd-${BOOST_VERSION})
- set(BOOST_SIGNALS_LIBRARY
- optimized libboost_signals-vc80-mt-${BOOST_VERSION}
- debug libboost_signals-vc80-mt-gd-${BOOST_VERSION})
- set(BOOST_SYSTEM_LIBRARY
- optimized libboost_system-vc80-mt-${BOOST_VERSION}
- debug libboost_system-vc80-mt-gd-${BOOST_VERSION})
- set(BOOST_THREAD_LIBRARY
- optimized libboost_thread-vc80-mt-${BOOST_VERSION}
- debug libboost_thread-vc80-mt-gd-${BOOST_VERSION})
- else(MSVC80)
- # MSVC 10.0 config
- set(BOOST_CONTEXT_LIBRARY
- optimized libboost_context-mt${addrsfx}
- debug libboost_context-mt${addrsfx}-gd)
- set(BOOST_FIBER_LIBRARY
- optimized libboost_fiber-mt${addrsfx}
- debug libboost_fiber-mt${addrsfx}-gd)
- set(BOOST_FILESYSTEM_LIBRARY
- optimized libboost_filesystem-mt${addrsfx}
- debug libboost_filesystem-mt${addrsfx}-gd)
- set(BOOST_PROGRAM_OPTIONS_LIBRARY
- optimized libboost_program_options-mt${addrsfx}
- debug libboost_program_options-mt${addrsfx}-gd)
- set(BOOST_REGEX_LIBRARY
- optimized libboost_regex-mt${addrsfx}
- debug libboost_regex-mt${addrsfx}-gd)
- set(BOOST_SIGNALS_LIBRARY
- optimized libboost_signals-mt${addrsfx}
- debug libboost_signals-mt${addrsfx}-gd)
- set(BOOST_SYSTEM_LIBRARY
- optimized libboost_system-mt${addrsfx}
- debug libboost_system-mt${addrsfx}-gd)
- set(BOOST_THREAD_LIBRARY
- optimized libboost_thread-mt${addrsfx}
- debug libboost_thread-mt${addrsfx}-gd)
- endif (MSVC80)
+ set(BOOST_CONTEXT_LIBRARY
+ optimized libboost_context-mt${addrsfx}
+ debug libboost_context-mt${addrsfx}-gd)
+ set(BOOST_FIBER_LIBRARY
+ optimized libboost_fiber-mt${addrsfx}
+ debug libboost_fiber-mt${addrsfx}-gd)
+ set(BOOST_FILESYSTEM_LIBRARY
+ optimized libboost_filesystem-mt${addrsfx}
+ debug libboost_filesystem-mt${addrsfx}-gd)
+ set(BOOST_PROGRAM_OPTIONS_LIBRARY
+ optimized libboost_program_options-mt${addrsfx}
+ debug libboost_program_options-mt${addrsfx}-gd)
+ set(BOOST_REGEX_LIBRARY
+ optimized libboost_regex-mt${addrsfx}
+ debug libboost_regex-mt${addrsfx}-gd)
+ set(BOOST_SIGNALS_LIBRARY
+ optimized libboost_signals-mt${addrsfx}
+ debug libboost_signals-mt${addrsfx}-gd)
+ set(BOOST_SYSTEM_LIBRARY
+ optimized libboost_system-mt${addrsfx}
+ debug libboost_system-mt${addrsfx}-gd)
+ set(BOOST_THREAD_LIBRARY
+ optimized libboost_thread-mt${addrsfx}
+ debug libboost_thread-mt${addrsfx}-gd)
elseif (LINUX)
set(BOOST_CONTEXT_LIBRARY
optimized boost_context-mt${addrsfx}
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 50cd42ff57..4d70089737 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -10,7 +10,6 @@ set(cmake_SOURCE_FILES
00-Common.cmake
APR.cmake
Audio.cmake
- BerkeleyDB.cmake
Boost.cmake
bugsplat.cmake
BuildVersion.cmake
@@ -26,7 +25,6 @@ set(cmake_SOURCE_FILES
EXPAT.cmake
FindAPR.cmake
FindAutobuild.cmake
- FindBerkeleyDB.cmake
FindGLH.cmake
FindHUNSPELL.cmake
FindJsonCpp.cmake
@@ -35,7 +33,7 @@ set(cmake_SOURCE_FILES
FindSCP.cmake
FindURIPARSER.cmake
FindXmlRpcEpi.cmake
- FindZLIB.cmake
+ FindZLIBNG.cmake
FMODSTUDIO.cmake
FreeType.cmake
GLEXT.cmake
@@ -93,7 +91,7 @@ set(cmake_SOURCE_FILES
VisualLeakDetector.cmake
LibVLCPlugin.cmake
XmlRpcEpi.cmake
- ZLIB.cmake
+ ZLIBNG.cmake
)
source_group("Shared Rules" FILES ${cmake_SOURCE_FILES})
diff --git a/indra/cmake/FindBerkeleyDB.cmake b/indra/cmake/FindBerkeleyDB.cmake
deleted file mode 100644
index 2d633c74ec..0000000000
--- a/indra/cmake/FindBerkeleyDB.cmake
+++ /dev/null
@@ -1,50 +0,0 @@
-# -*- cmake -*-
-
-# - Find BerkeleyDB
-# Find the BerkeleyDB includes and library
-# This module defines
-# DB_INCLUDE_DIR, where to find db.h, etc.
-# DB_LIBRARIES, the libraries needed to use BerkeleyDB.
-# DB_FOUND, If false, do not try to use BerkeleyDB.
-# also defined, but not for general use are
-# DB_LIBRARY, where to find the BerkeleyDB library.
-
-FIND_PATH(DB_INCLUDE_DIR db.h
-/usr/local/include/db4
-/usr/local/include
-/usr/include/db4
-/usr/include
-)
-
-SET(DB_NAMES ${DB_NAMES} db)
-FIND_LIBRARY(DB_LIBRARY
- NAMES ${DB_NAMES}
- PATHS /usr/lib /usr/local/lib
- )
-
-IF (DB_LIBRARY AND DB_INCLUDE_DIR)
- SET(DB_LIBRARIES ${DB_LIBRARY})
- SET(DB_FOUND "YES")
-ELSE (DB_LIBRARY AND DB_INCLUDE_DIR)
- SET(DB_FOUND "NO")
-ENDIF (DB_LIBRARY AND DB_INCLUDE_DIR)
-
-
-IF (DB_FOUND)
- IF (NOT DB_FIND_QUIETLY)
- MESSAGE(STATUS "Found BerkeleyDB: ${DB_LIBRARIES}")
- ENDIF (NOT DB_FIND_QUIETLY)
-ELSE (DB_FOUND)
- IF (DB_FIND_REQUIRED)
- MESSAGE(FATAL_ERROR "Could not find BerkeleyDB library")
- ENDIF (DB_FIND_REQUIRED)
-ENDIF (DB_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_DB_INCLUDE_PATH ${DB_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_DB_LIB_PATH ${DB_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
- DB_LIBRARY
- DB_INCLUDE_DIR
- )
diff --git a/indra/cmake/FindZLIB.cmake b/indra/cmake/FindZLIB.cmake
deleted file mode 100644
index 03a7db9d6f..0000000000
--- a/indra/cmake/FindZLIB.cmake
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- cmake -*-
-
-# - Find zlib
-# Find the ZLIB includes and library
-# This module defines
-# ZLIB_INCLUDE_DIRS, where to find zlib.h, etc.
-# ZLIB_LIBRARIES, the libraries needed to use zlib.
-# ZLIB_FOUND, If false, do not try to use zlib.
-#
-# This FindZLIB is about 43 times as fast the one provided with cmake (2.8.x),
-# because it doesn't look up the version of zlib, resulting in a dramatic
-# speed up for configure (from 4 minutes 22 seconds to 6 seconds).
-#
-# Note: Since this file is only used for standalone, the windows
-# specific parts were left out.
-
-FIND_PATH(ZLIB_INCLUDE_DIR zlib.h
- NO_SYSTEM_ENVIRONMENT_PATH
- )
-
-FIND_LIBRARY(ZLIB_LIBRARY z)
-
-if (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
- SET(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
- SET(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
- SET(ZLIB_FOUND "YES")
-else (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
- SET(ZLIB_FOUND "NO")
-endif (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
-
-if (ZLIB_FOUND)
- if (NOT ZLIB_FIND_QUIETLY)
- message(STATUS "Found ZLIB: ${ZLIB_LIBRARIES}")
- SET(ZLIB_FIND_QUIETLY TRUE)
- endif (NOT ZLIB_FIND_QUIETLY)
-else (ZLIB_FOUND)
- if (ZLIB_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find ZLIB library")
- endif (ZLIB_FIND_REQUIRED)
-endif (ZLIB_FOUND)
-
-mark_as_advanced(
- ZLIB_LIBRARY
- ZLIB_INCLUDE_DIR
- )
-
diff --git a/indra/cmake/FindZLIBNG.cmake b/indra/cmake/FindZLIBNG.cmake
new file mode 100644
index 0000000000..6e3c8cdddb
--- /dev/null
+++ b/indra/cmake/FindZLIBNG.cmake
@@ -0,0 +1,46 @@
+# -*- cmake -*-
+
+# - Find zlib-ng
+# Find the ZLIB includes and library
+# This module defines
+# ZLIBNG_INCLUDE_DIRS, where to find zlib.h, etc.
+# ZLIBNG_LIBRARIES, the libraries needed to use zlib.
+# ZLIBNG_FOUND, If false, do not try to use zlib.
+#
+# This FindZLIBNG is about 43 times as fast the one provided with cmake (2.8.x),
+# because it doesn't look up the version of zlib, resulting in a dramatic
+# speed up for configure (from 4 minutes 22 seconds to 6 seconds).
+#
+# Note: Since this file is only used for standalone, the windows
+# specific parts were left out.
+
+FIND_PATH(ZLIBNG_INCLUDE_DIR zlib.h
+ NO_SYSTEM_ENVIRONMENT_PATH
+ )
+
+FIND_LIBRARY(ZLIBNG_LIBRARY z)
+
+if (ZLIBNG_LIBRARY AND ZLIBNG_INCLUDE_DIR)
+ SET(ZLIBNG_INCLUDE_DIRS ${ZLIBNG_INCLUDE_DIR})
+ SET(ZLIBNG_LIBRARIES ${ZLIBNG_LIBRARY})
+ SET(ZLIBNG_FOUND "YES")
+else (ZLIBNG_LIBRARY AND ZLIBNG_INCLUDE_DIR)
+ SET(ZLIBNG_FOUND "NO")
+endif (ZLINGB_LIBRARY AND ZLIBNG_INCLUDE_DIR)
+
+if (ZLIBNG_FOUND)
+ if (NOT ZLIBNG_FIND_QUIETLY)
+ message(STATUS "Found ZLIBNG: ${ZLIBNG_LIBRARIES}")
+ SET(ZLIBNG_FIND_QUIETLY TRUE)
+ endif (NOT ZLIBNG_FIND_QUIETLY)
+else (ZLIBNG_FOUND)
+ if (ZLIBNG_FIND_REQUIRED)
+ message(FATAL_ERROR "Could not find ZLIBNG library")
+ endif (ZLIBNG_FIND_REQUIRED)
+endif (ZLIBNG_FOUND)
+
+mark_as_advanced(
+ ZLIBNG_LIBRARY
+ ZLIBNG_INCLUDE_DIR
+ )
+
diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake
index 9fd3923bfd..a749644202 100644
--- a/indra/cmake/GLEXT.cmake
+++ b/indra/cmake/GLEXT.cmake
@@ -2,9 +2,7 @@
include(Prebuilt)
if (NOT USESYSTEMLIBS)
- if (WINDOWS OR LINUX)
- use_prebuilt_binary(glext)
- endif (WINDOWS OR LINUX)
+ use_prebuilt_binary(glext)
use_prebuilt_binary(glh_linear)
set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
endif (NOT USESYSTEMLIBS)
diff --git a/indra/cmake/LLAppearanceUtility.cmake b/indra/cmake/LLAppearanceUtility.cmake
index 28b49bf75f..0eb3c723d5 100644
--- a/indra/cmake/LLAppearanceUtility.cmake
+++ b/indra/cmake/LLAppearanceUtility.cmake
@@ -10,5 +10,3 @@ if (INSTALL_PROPRIETARY)
set(LLAPPEARANCEUTILITY_BIN_DIR ${CMAKE_BINARY_DIR}/llappearanceutility)
endif (LINUX)
endif (INSTALL_PROPRIETARY)
-
-
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index 34499aaa36..53871791fd 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -4,7 +4,7 @@ include(APR)
include(Boost)
include(EXPAT)
include(Tracy)
-include(ZLIB)
+include(ZLIBNG)
set(LLCOMMON_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llcommon
diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake
index 893920ae6f..513ff9f81d 100644
--- a/indra/cmake/LLMath.cmake
+++ b/indra/cmake/LLMath.cmake
@@ -1,5 +1,9 @@
# -*- cmake -*-
+include(Variables)
+include(Mikktspace)
+include(MESHOPTIMIZER)
+
set(LLMATH_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llmath
)
diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake
index 93626f689f..4e34951215 100644
--- a/indra/cmake/LLPrimitive.cmake
+++ b/indra/cmake/LLPrimitive.cmake
@@ -5,6 +5,7 @@ include(Prebuilt)
include(Boost)
use_prebuilt_binary(colladadom)
+use_prebuilt_binary(minizip-ng) # needed for colladadom
use_prebuilt_binary(pcre)
use_prebuilt_binary(libxml2)
@@ -22,6 +23,8 @@ if (WINDOWS)
optimized pcrecpp
debug pcred
optimized pcre
+ debug libminizip
+ optimized libminizip
${BOOST_SYSTEM_LIBRARIES}
)
elseif (DARWIN)
@@ -29,7 +32,7 @@ elseif (DARWIN)
llprimitive
debug collada14dom-d
optimized collada14dom
- minizip
+ minizip # for collada libminizip.a
xml2
pcrecpp
pcre
diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake
index 868922451f..2d9d3725ad 100644
--- a/indra/cmake/LLRender.cmake
+++ b/indra/cmake/LLRender.cmake
@@ -3,10 +3,12 @@
include(Variables)
include(FreeType)
include(GLH)
+include(GLEXT)
set(LLRENDER_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llrender
${GLH_INCLUDE_DIR}
+ ${GLEXT_INCLUDE_DIR}
)
if (BUILD_HEADLESS)
diff --git a/indra/cmake/Mikktspace.cmake b/indra/cmake/Mikktspace.cmake
new file mode 100644
index 0000000000..9fd2becba4
--- /dev/null
+++ b/indra/cmake/Mikktspace.cmake
@@ -0,0 +1,6 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+if (NOT USESYSTEMLIBS)
+ use_prebuilt_binary(mikktspace)
+endif (NOT USESYSTEMLIBS)
diff --git a/indra/cmake/TinyGLTF.cmake b/indra/cmake/TinyGLTF.cmake
new file mode 100644
index 0000000000..bb731637a0
--- /dev/null
+++ b/indra/cmake/TinyGLTF.cmake
@@ -0,0 +1,7 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+use_prebuilt_binary(tinygltf)
+
+set(TINYGLTF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tinygltf)
+
diff --git a/indra/cmake/VulkanGltf.cmake b/indra/cmake/VulkanGltf.cmake
new file mode 100644
index 0000000000..94541d5307
--- /dev/null
+++ b/indra/cmake/VulkanGltf.cmake
@@ -0,0 +1,5 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+use_prebuilt_binary(vulkan_gltf)
+
diff --git a/indra/cmake/ZLIB.cmake b/indra/cmake/ZLIBNG.cmake
index 6cff0753b2..1f46a23d92 100644
--- a/indra/cmake/ZLIB.cmake
+++ b/indra/cmake/ZLIBNG.cmake
@@ -1,17 +1,17 @@
# -*- cmake -*-
-set(ZLIB_FIND_QUIETLY ON)
-set(ZLIB_FIND_REQUIRED ON)
+set(ZLIBNG_FIND_QUIETLY ON)
+set(ZLIBNG_FIND_REQUIRED ON)
include(Prebuilt)
if (USESYSTEMLIBS)
- include(FindZLIB)
+ include(FindZLIBNG)
else (USESYSTEMLIBS)
- use_prebuilt_binary(zlib)
+ use_prebuilt_binary(zlib-ng)
if (WINDOWS)
- set(ZLIB_LIBRARIES
- debug zlibd
+ set(ZLIBNG_LIBRARIES
+ debug zlib
optimized zlib)
elseif (LINUX)
#
@@ -26,10 +26,10 @@ else (USESYSTEMLIBS)
# second whole-archive load of the archive. See viewer's
# CMakeLists.txt for more information.
#
- set(ZLIB_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive)
- set(ZLIB_LIBRARIES z)
+ set(ZLIBNG_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive)
+ set(ZLIBNG_LIBRARIES z)
elseif (DARWIN)
- set(ZLIB_LIBRARIES z)
+ set(ZLIBNG_LIBRARIES z)
endif (WINDOWS)
- set(ZLIB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib)
+ set(ZLIBNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib-ng)
endif (USESYSTEMLIBS)
diff --git a/indra/doxygen/CMakeLists.txt b/indra/doxygen/CMakeLists.txt
index 84188bd32f..616b5cd09c 100644
--- a/indra/doxygen/CMakeLists.txt
+++ b/indra/doxygen/CMakeLists.txt
@@ -4,7 +4,7 @@
# other commands to guarantee full compatibility
# with the version specified
## prior to 2.8, the add_custom_target commands used in setting the version did not work correctly
-cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
"The root project/makefile/solution name. Defaults to SecondLife.")
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index aedd3b7ee4..5b277846b7 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -83,8 +83,7 @@ def proper_windows_path(path, current_platform = sys.platform):
return drive_letter.upper() + ':\\' + rel.replace('/', '\\')
def get_default_platform(dummy):
- return {'linux2':'linux',
- 'linux1':'linux',
+ return {'linux':'linux',
'cygwin':'windows',
'win32':'windows',
'darwin':'darwin'
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 2d6d2a10d2..f0df3e1474 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -927,6 +927,9 @@ BOOL LLAvatarAppearance::loadAvatar()
return FALSE;
}
+ // initialize mJointAliasMap
+ getJointAliases();
+
// avatar_lad.xml : <skeleton>
if( !loadSkeletonNode() )
{
@@ -1047,7 +1050,6 @@ BOOL LLAvatarAppearance::loadAvatar()
return FALSE;
}
}
-
return TRUE;
}
diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
index 0a7a8d27bb..3892e4ce43 100644
--- a/indra/llappearance/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -612,14 +612,16 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
// we reached the end of the morphs
break;
}
- LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName));
+ std::string morph_name(morphName);
+ LLPolyMorphData* morph_data = new LLPolyMorphData(morph_name);
BOOL result = morph_data->loadBinary(fp, this);
if (!result)
{
- delete morph_data;
- continue;
+ LL_WARNS() << "Failure loading " << morph_name << " from " << fileName << LL_ENDL;
+ delete morph_data;
+ continue;
}
mMorphData.insert(morph_data);
diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
index 16b5f1e204..84dd6156a9 100644
--- a/indra/llappearance/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -156,7 +156,9 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
if (mVertexIndices[v] > 10000)
{
- LL_ERRS() << "Bad morph index: " << mVertexIndices[v] << LL_ENDL;
+ // Bad install? These are usually .llm files from 'character' fodler
+ LL_WARNS() << "Bad morph index " << v << ": " << mVertexIndices[v] << LL_ENDL;
+ return FALSE;
}
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index 234f5c3007..e1a3a83841 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -446,32 +446,6 @@ const std::string LLTexLayerSet::getBodyRegionName() const
return mInfo->mBodyRegion;
}
-
-// virtual
-void LLTexLayerSet::asLLSD(LLSD& sd) const
-{
- sd["visible"] = LLSD::Boolean(isVisible());
- LLSD layer_list_sd;
- layer_list_t::const_iterator layer_iter = mLayerList.begin();
- layer_list_t::const_iterator layer_end = mLayerList.end();
- for(; layer_iter != layer_end; ++layer_iter);
- {
- LLSD layer_sd;
- //LLTexLayerInterface* layer = (*layer_iter);
- //if (layer)
- //{
- // layer->asLLSD(layer_sd);
- //}
- layer_list_sd.append(layer_sd);
- }
- LLSD mask_list_sd;
- LLSD info_sd;
- sd["layers"] = layer_list_sd;
- sd["masks"] = mask_list_sd;
- sd["info"] = info_sd;
-}
-
-
void LLTexLayerSet::destroyComposite()
{
if( mComposite )
@@ -1535,7 +1509,14 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
}
else
{ // platforms with working drivers...
- glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
+ // We just want GL_ALPHA, but that isn't supported in OGL core profile 4.
+ static const size_t TEMP_BYTES_PER_PIXEL = 4;
+ U8* temp_data = (U8*)ll_aligned_malloc_32(mem_size * TEMP_BYTES_PER_PIXEL);
+ glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_data);
+ for (size_t pixel = 0; pixel < pixels; pixel++) {
+ alpha_data[pixel] = temp_data[(pixel * TEMP_BYTES_PER_PIXEL) + 3];
+ }
+ ll_aligned_free_32(temp_data);
}
}
else
diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h
index 6a5040cf0b..74b421d3ee 100644
--- a/indra/llappearance/lltexlayer.h
+++ b/indra/llappearance/lltexlayer.h
@@ -220,8 +220,6 @@ public:
static BOOL sHasCaches;
- virtual void asLLSD(LLSD& sd) const;
-
protected:
typedef std::vector<LLTexLayerInterface *> layer_list_t;
layer_list_t mLayerList;
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index ff0aa6e76e..38a6b41afe 100644..100755
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -35,6 +35,8 @@
#include "llendianswizzle.h"
#include "llassetstorage.h"
#include "llrefcount.h"
+#include "threadpool.h"
+#include "workqueue.h"
#include "llvorbisencode.h"
@@ -45,15 +47,13 @@
extern LLAudioEngine *gAudiop;
-LLAudioDecodeMgr *gAudioDecodeMgrp = NULL;
-
static const S32 WAV_HEADER_SIZE = 44;
//////////////////////////////////////////////////////////////////////////////
-class LLVorbisDecodeState : public LLRefCount
+class LLVorbisDecodeState : public LLThreadSafeRefCount
{
public:
class WriteResponder : public LLLFSThread::Responder
@@ -532,146 +532,254 @@ void LLVorbisDecodeState::flushBadFile()
class LLAudioDecodeMgr::Impl
{
- friend class LLAudioDecodeMgr;
-public:
- Impl() {};
- ~Impl() {};
+ friend class LLAudioDecodeMgr;
+ Impl();
+ public:
- void processQueue(const F32 num_secs = 0.005);
+ void processQueue();
-protected:
- std::deque<LLUUID> mDecodeQueue;
- LLPointer<LLVorbisDecodeState> mCurrentDecodep;
+ void startMoreDecodes();
+ void enqueueFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState>& decode_state);
+ void checkDecodesFinished();
+
+ protected:
+ std::deque<LLUUID> mDecodeQueue;
+ std::map<LLUUID, LLPointer<LLVorbisDecodeState>> mDecodes;
};
+LLAudioDecodeMgr::Impl::Impl()
+{
+}
+
+// Returns the in-progress decode_state, which may be an empty LLPointer if
+// there was an error and there is no more work to be done.
+LLPointer<LLVorbisDecodeState> beginDecodingAndWritingAudio(const LLUUID &decode_id);
-void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
+// Return true if finished
+bool tryFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState> decode_state);
+
+void LLAudioDecodeMgr::Impl::processQueue()
{
- LLUUID uuid;
+ // First, check if any audio from in-progress decodes are ready to play. If
+ // so, mark them ready for playback (or errored, in case of error).
+ checkDecodesFinished();
- LLTimer decode_timer;
+ // Second, start as many decodes from the queue as permitted
+ startMoreDecodes();
+}
- BOOL done = FALSE;
- while (!done)
- {
- if (mCurrentDecodep)
- {
- BOOL res;
+void LLAudioDecodeMgr::Impl::startMoreDecodes()
+{
+ llassert_always(gAudiop);
+
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak
+ // pointer
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ const LL::ThreadPool::ptr_t general_thread_pool = LL::ThreadPool::getInstance("General");
+ llassert_always(main_queue);
+ llassert_always(general_queue);
+ llassert_always(general_thread_pool);
+ // Set max decodes to double the thread count of the general work queue.
+ // This ensures the general work queue is full, but prevents theoretical
+ // buildup of buffers in memory due to disk writes once the
+ // LLVorbisDecodeState leaves the worker thread (see
+ // LLLFSThread::sLocal->write). This is probably as fast as we can get it
+ // without modifying/removing LLVorbisDecodeState, at which point we should
+ // consider decoding the audio during the asset download process.
+ // -Cosmic,2022-05-11
+ const size_t max_decodes = general_thread_pool->getWidth() * 2;
+
+ while (!mDecodeQueue.empty() && mDecodes.size() < max_decodes)
+ {
+ const LLUUID decode_id = mDecodeQueue.front();
+ mDecodeQueue.pop_front();
+
+ // Don't decode the same file twice
+ if (mDecodes.find(decode_id) != mDecodes.end())
+ {
+ continue;
+ }
+ if (gAudiop->hasDecodedFile(decode_id))
+ {
+ continue;
+ }
+
+ // Kick off a decode
+ mDecodes[decode_id] = LLPointer<LLVorbisDecodeState>(NULL);
+ try
+ {
+ main_queue->postTo(
+ general_queue,
+ [decode_id]() // Work done on general queue
+ {
+ LLPointer<LLVorbisDecodeState> decode_state = beginDecodingAndWritingAudio(decode_id);
+
+ if (!decode_state)
+ {
+ // Audio decode has errored
+ return decode_state;
+ }
+
+ // Disk write of decoded audio is now in progress off-thread
+ return decode_state;
+ },
+ [decode_id, this](LLPointer<LLVorbisDecodeState> decode_state) // Callback to main thread
+ mutable {
+ if (!gAudiop)
+ {
+ // There is no LLAudioEngine anymore. This might happen if
+ // an audio decode is enqueued just before shutdown.
+ return;
+ }
+
+ // At this point, we can be certain that the pointer to "this"
+ // is valid because the lifetime of "this" is dependent upon
+ // the lifetime of gAudiop.
+
+ enqueueFinishAudio(decode_id, decode_state);
+ });
+ }
+ catch (const LLThreadSafeQueueInterrupt&)
+ {
+ // Shutdown
+ // Consider making processQueue() do a cleanup instead
+ // of starting more decodes
+ LL_WARNS() << "Tried to start decoding on shutdown" << LL_ENDL;
+ }
+ }
+}
- // Decode in a loop until we're done or have run out of time.
- while(!(res = mCurrentDecodep->decodeSection()) && (decode_timer.getElapsedTimeF32() < num_secs))
- {
- // decodeSection does all of the work above
- }
+LLPointer<LLVorbisDecodeState> beginDecodingAndWritingAudio(const LLUUID &decode_id)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
+
+ LL_DEBUGS() << "Decoding " << decode_id << " from audio queue!" << LL_ENDL;
+
+ std::string d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, decode_id.asString()) + ".dsf";
+ LLPointer<LLVorbisDecodeState> decode_state = new LLVorbisDecodeState(decode_id, d_path);
+
+ if (!decode_state->initDecode())
+ {
+ return NULL;
+ }
+
+ // Decode in a loop until we're done
+ while (!decode_state->decodeSection())
+ {
+ // decodeSection does all of the work above
+ }
+
+ if (!decode_state->isDone())
+ {
+ // Decode stopped early, or something bad happened to the file
+ // during decoding.
+ LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data or decode has been canceled, aborting decode" << LL_ENDL;
+ decode_state->flushBadFile();
+ return NULL;
+ }
+
+ if (!decode_state->isValid())
+ {
+ // We had an error when decoding, abort.
+ LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data, aborting decode" << LL_ENDL;
+ decode_state->flushBadFile();
+ return NULL;
+ }
+
+ // Kick off the writing of the decoded audio to the disk cache.
+ // The receiving thread can then cheaply call finishDecode() again to check
+ // if writing has finished. Someone has to hold on to the refcounted
+ // decode_state to prevent it from getting destroyed during write.
+ decode_state->finishDecode();
+
+ return decode_state;
+}
- if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid())
- {
- // We had an error when decoding, abort.
- LL_WARNS("AudioEngine") << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << LL_ENDL;
- mCurrentDecodep->flushBadFile();
-
- if (gAudiop)
- {
- LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
- adp->setHasValidData(false);
- adp->setHasCompletedDecode(true);
- }
-
- mCurrentDecodep = NULL;
- done = TRUE;
- }
+void LLAudioDecodeMgr::Impl::enqueueFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState>& decode_state)
+{
+ // Assumed fast
+ if (tryFinishAudio(decode_id, decode_state))
+ {
+ // Done early!
+ auto decode_iter = mDecodes.find(decode_id);
+ llassert(decode_iter != mDecodes.end());
+ mDecodes.erase(decode_iter);
+ return;
+ }
+
+ // Not done yet... enqueue it
+ mDecodes[decode_id] = decode_state;
+}
- if (!res)
- {
- // We've used up out time slice, bail...
- done = TRUE;
- }
- else if (mCurrentDecodep)
- {
- if (gAudiop && mCurrentDecodep->finishDecode())
- {
- // We finished!
- LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
- if (!adp)
- {
- LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << LL_ENDL;
- }
- else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
- {
- adp->setHasCompletedDecode(true);
- adp->setHasDecodedData(true);
- adp->setHasValidData(true);
-
- // At this point, we could see if anyone needs this sound immediately, but
- // I'm not sure that there's a reason to - we need to poll all of the playing
- // sounds anyway.
- //LL_INFOS("AudioEngine") << "Finished the vorbis decode, now what?" << LL_ENDL;
- }
- else
- {
- adp->setHasCompletedDecode(true);
- LL_INFOS("AudioEngine") << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << LL_ENDL;
- }
- mCurrentDecodep = NULL;
- }
- done = TRUE; // done for now
- }
- }
+void LLAudioDecodeMgr::Impl::checkDecodesFinished()
+{
+ auto decode_iter = mDecodes.begin();
+ while (decode_iter != mDecodes.end())
+ {
+ const LLUUID& decode_id = decode_iter->first;
+ const LLPointer<LLVorbisDecodeState>& decode_state = decode_iter->second;
+ if (tryFinishAudio(decode_id, decode_state))
+ {
+ decode_iter = mDecodes.erase(decode_iter);
+ }
+ else
+ {
+ ++decode_iter;
+ }
+ }
+}
- if (!done)
- {
- if (mDecodeQueue.empty())
- {
- // Nothing else on the queue.
- done = TRUE;
- }
- else
- {
- LLUUID uuid;
- uuid = mDecodeQueue.front();
- mDecodeQueue.pop_front();
- if (!gAudiop || gAudiop->hasDecodedFile(uuid))
- {
- // This file has already been decoded, don't decode it again.
- continue;
- }
-
- LL_DEBUGS() << "Decoding " << uuid << " from audio queue!" << LL_ENDL;
-
- std::string uuid_str;
- std::string d_path;
-
- LLTimer timer;
- timer.reset();
-
- uuid.toString(uuid_str);
- d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf";
-
- mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path);
- if (!mCurrentDecodep->initDecode())
- {
- mCurrentDecodep = NULL;
- }
- }
- }
- }
+bool tryFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState> decode_state)
+{
+ // decode_state is a file write in progress unless finished is true
+ bool finished = decode_state && decode_state->finishDecode();
+ if (!finished)
+ {
+ return false;
+ }
+
+ llassert_always(gAudiop);
+
+ LLAudioData *adp = gAudiop->getAudioData(decode_id);
+ if (!adp)
+ {
+ LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << decode_id << LL_ENDL;
+ return true;
+ }
+
+ bool valid = decode_state && decode_state->isValid();
+ // Mark current decode finished regardless of success or failure
+ adp->setHasCompletedDecode(true);
+ // Flip flags for decoded data
+ adp->setHasDecodeFailed(!valid);
+ adp->setHasDecodedData(valid);
+ // When finished decoding, there will also be a decoded wav file cached on
+ // disk with the .dsf extension
+ if (valid)
+ {
+ adp->setHasWAVLoadFailed(false);
+ }
+
+ return true;
}
//////////////////////////////////////////////////////////////////////////////
LLAudioDecodeMgr::LLAudioDecodeMgr()
{
- mImpl = new Impl;
+ mImpl = new Impl();
}
LLAudioDecodeMgr::~LLAudioDecodeMgr()
{
- delete mImpl;
+ delete mImpl;
+ mImpl = nullptr;
}
-void LLAudioDecodeMgr::processQueue(const F32 num_secs)
+void LLAudioDecodeMgr::processQueue()
{
- mImpl->processQueue(num_secs);
+ mImpl->processQueue();
}
BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
@@ -687,7 +795,7 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
{
// Just put it on the decode queue.
LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL;
- mImpl->mDecodeQueue.push_back(uuid);
+ mImpl->mDecodeQueue.push_back(uuid);
return TRUE;
}
diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h
index ceaff3f2d8..4c17b46156 100644
--- a/indra/llaudio/llaudiodecodemgr.h
+++ b/indra/llaudio/llaudiodecodemgr.h
@@ -32,24 +32,23 @@
#include "llassettype.h"
#include "llframetimer.h"
+#include "llsingleton.h"
+template<class T> class LLPointer;
class LLVorbisDecodeState;
-class LLAudioDecodeMgr
+class LLAudioDecodeMgr : public LLSingleton<LLAudioDecodeMgr>
{
+ LLSINGLETON(LLAudioDecodeMgr);
+ ~LLAudioDecodeMgr();
public:
- LLAudioDecodeMgr();
- ~LLAudioDecodeMgr();
-
- void processQueue(const F32 num_secs = 0.005);
+ void processQueue();
BOOL addDecodeRequest(const LLUUID &uuid);
void addAudioRequest(const LLUUID &uuid);
protected:
class Impl;
- Impl* mImpl;
+ Impl* mImpl;
};
-extern LLAudioDecodeMgr *gAudioDecodeMgrp;
-
#endif
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index e0ebbb76bd..008e1827c5 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -83,18 +83,10 @@ void LLAudioEngine::setDefaults()
mLastStatus = 0;
- mNumChannels = 0;
mEnableWind = false;
- S32 i;
- for (i = 0; i < MAX_CHANNELS; i++)
- {
- mChannels[i] = NULL;
- }
- for (i = 0; i < MAX_BUFFERS; i++)
- {
- mBuffers[i] = NULL;
- }
+ mChannels.fill(nullptr);
+ mBuffers.fill(nullptr);
mMasterGain = 1.f;
// Setting mInternalGain to an out of range value fixes the issue reported in STORM-830.
@@ -111,18 +103,14 @@ void LLAudioEngine::setDefaults()
}
-bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title)
+bool LLAudioEngine::init(void* userdata, const std::string &app_title)
{
setDefaults();
- mNumChannels = num_channels;
mUserData = userdata;
allocateListener();
- // Initialize the decode manager
- gAudioDecodeMgrp = new LLAudioDecodeMgr;
-
LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL;
return true;
@@ -131,10 +119,6 @@ bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::stri
void LLAudioEngine::shutdown()
{
- // Clean up decode manager
- delete gAudioDecodeMgrp;
- gAudioDecodeMgrp = NULL;
-
// Clean up wind source
cleanupWind();
@@ -156,14 +140,14 @@ void LLAudioEngine::shutdown()
// Clean up channels
S32 i;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
delete mChannels[i];
mChannels[i] = NULL;
}
// Clean up buffers
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
delete mBuffers[i];
mBuffers[i] = NULL;
@@ -229,7 +213,7 @@ std::string LLAudioEngine::getInternetStreamURL()
void LLAudioEngine::updateChannels()
{
S32 i;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (mChannels[i])
{
@@ -240,20 +224,14 @@ void LLAudioEngine::updateChannels()
}
}
-static const F32 default_max_decode_time = .002f; // 2 ms
-void LLAudioEngine::idle(F32 max_decode_time)
+void LLAudioEngine::idle()
{
- if (max_decode_time <= 0.f)
- {
- max_decode_time = default_max_decode_time;
- }
-
// "Update" all of our audio sources, clean up dead ones.
// Primarily does position updating, cleanup of unused audio sources.
// Also does regeneration of the current priority of each audio source.
S32 i;
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (mBuffers[i])
{
@@ -276,7 +254,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
{
// The source is done playing, clean it up.
delete sourcep;
- mAllSources.erase(iter++);
+ iter = mAllSources.erase(iter);
continue;
}
@@ -473,7 +451,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
commitDeferredChanges();
// Flush unused buffers that are stale enough
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (mBuffers[i])
{
@@ -489,7 +467,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
// Clear all of the looped flags for the channels
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (mChannels[i])
{
@@ -498,7 +476,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
}
// Decode audio files
- gAudioDecodeMgrp->processQueue(max_decode_time);
+ LLAudioDecodeMgr::getInstance()->processQueue();
// Call this every frame, just in case we somehow
// missed picking it up in all the places that can add
@@ -532,7 +510,7 @@ bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uu
{
if (audio_uuid.notNull())
{
- gAudioDecodeMgrp->addDecodeRequest(audio_uuid);
+ LLAudioDecodeMgr::getInstance()->addDecodeRequest(audio_uuid);
}
}
else
@@ -561,7 +539,7 @@ void LLAudioEngine::enableWind(bool enable)
LLAudioBuffer * LLAudioEngine::getFreeBuffer()
{
S32 i;
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (!mBuffers[i])
{
@@ -574,7 +552,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer()
// Grab the oldest unused buffer
F32 max_age = -1.f;
S32 buffer_id = -1;
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (mBuffers[i])
{
@@ -605,7 +583,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer()
LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
{
S32 i;
- for (i = 0; i < mNumChannels; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (!mChannels[i])
{
@@ -633,7 +611,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
F32 min_priority = 10000.f;
LLAudioChannel *min_channelp = NULL;
- for (i = 0; i < mNumChannels; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
LLAudioChannel *channelp = mChannels[i];
LLAudioSource *sourcep = channelp->getSource();
@@ -660,7 +638,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp)
{
S32 i;
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (mBuffers[i] == bufferp)
{
@@ -678,7 +656,7 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid)
getAudioData(uuid); // We don't care about the return value, this is just to make sure
// that we have an entry, which will mean that the audio engine knows about this
- if (gAudioDecodeMgrp->addDecodeRequest(uuid))
+ if (LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid))
{
// This means that we do have a local copy, and we're working on decoding it.
return true;
@@ -827,7 +805,8 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
addAudioSource(asp);
if (pos_global.isExactlyZero())
{
- asp->setAmbient(true);
+ // For sound preview and UI
+ asp->setForcedPriority(true);
}
else
{
@@ -953,6 +932,7 @@ LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id)
LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
data_map::iterator iter;
iter = mAllData.find(audio_uuid);
if (iter == mAllData.end())
@@ -1039,7 +1019,7 @@ void LLAudioEngine::startNextTransfer()
// Check all channels for currently playing sounds.
F32 max_pri = -1.f;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (!mChannels[i])
{
@@ -1067,7 +1047,7 @@ void LLAudioEngine::startNextTransfer()
continue;
}
- if (!adp->hasLocalData() && adp->hasValidData())
+ if (!adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1078,7 +1058,7 @@ void LLAudioEngine::startNextTransfer()
if (asset_id.isNull())
{
max_pri = -1.f;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (!mChannels[i])
{
@@ -1103,7 +1083,7 @@ void LLAudioEngine::startNextTransfer()
continue;
}
- if (!adp->hasLocalData() && adp->hasValidData())
+ if (!adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1115,7 +1095,7 @@ void LLAudioEngine::startNextTransfer()
if (asset_id.isNull())
{
max_pri = -1.f;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (!mChannels[i])
{
@@ -1143,7 +1123,7 @@ void LLAudioEngine::startNextTransfer()
continue;
}
- if (!adp->hasLocalData() && adp->hasValidData())
+ if (!adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1171,7 +1151,7 @@ void LLAudioEngine::startNextTransfer()
}
adp = asp->getCurrentData();
- if (adp && !adp->hasLocalData() && adp->hasValidData())
+ if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1179,7 +1159,7 @@ void LLAudioEngine::startNextTransfer()
}
adp = asp->getQueuedData();
- if (adp && !adp->hasLocalData() && adp->hasValidData())
+ if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1194,7 +1174,7 @@ void LLAudioEngine::startNextTransfer()
continue;
}
- if (!adp->hasLocalData() && adp->hasValidData())
+ if (!adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1235,7 +1215,7 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v
LLAudioData *adp = gAudiop->getAudioData(uuid);
if (adp)
{ // Make sure everything is cleared
- adp->setHasValidData(false);
+ adp->setHasDecodeFailed(true);
adp->setHasLocalData(false);
adp->setHasDecodedData(false);
adp->setHasCompletedDecode(true);
@@ -1252,9 +1232,9 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v
else
{
// LL_INFOS() << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL;
- adp->setHasValidData(true);
+ adp->setHasDecodeFailed(false);
adp->setHasLocalData(true);
- gAudioDecodeMgrp->addDecodeRequest(uuid);
+ LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid);
}
}
gAudiop->mCurrentTransfer = LLUUID::null;
@@ -1273,7 +1253,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
mPriority(0.f),
mGain(gain),
mSourceMuted(false),
- mAmbient(false),
+ mForcedPriority(false),
mLoop(false),
mSyncMaster(false),
mSyncSlave(false),
@@ -1324,11 +1304,15 @@ void LLAudioSource::update()
{
// Hack - try and load the sound. Will do this as a callback
// on decode later.
- if (adp->load() && adp->getBuffer())
+ if (adp->getBuffer())
{
play(adp->getID());
}
- else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done
+ else if (adp->hasDecodedData() && !adp->hasWAVLoadFailed())
+ {
+ adp->load();
+ }
+ else if (adp->hasCompletedDecode() && adp->hasDecodeFailed()) // Only mark corrupted after decode is done
{
LL_WARNS() << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL;
mCorrupted = true ;
@@ -1339,7 +1323,7 @@ void LLAudioSource::update()
void LLAudioSource::updatePriority()
{
- if (isAmbient())
+ if (isForcedPriority())
{
mPriority = 1.f;
}
@@ -1624,12 +1608,12 @@ bool LLAudioSource::hasPendingPreloads() const
{
LLAudioData *adp = iter->second;
// note: a bad UUID will forever be !hasDecodedData()
- // but also !hasValidData(), hence the check for hasValidData()
+ // but also hasDecodeFailed(), hence the check for hasDecodeFailed()
if (!adp)
{
continue;
}
- if (!adp->hasDecodedData() && adp->hasValidData())
+ if (!adp->hasDecodedData() && !adp->hasDecodeFailed())
{
// This source is still waiting for a preload
return true;
@@ -1786,7 +1770,8 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
mHasLocalData(false),
mHasDecodedData(false),
mHasCompletedDecode(false),
- mHasValidData(true)
+ mHasDecodeFailed(false),
+ mHasWAVLoadFailed(false)
{
if (uuid.isNull())
{
@@ -1821,12 +1806,14 @@ bool LLAudioData::load()
{
// We already have this sound in a buffer, don't do anything.
LL_INFOS() << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL;
+ mHasWAVLoadFailed = false;
return true;
}
if (!gAudiop)
{
LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ mHasWAVLoadFailed = true;
return false;
}
@@ -1835,6 +1822,8 @@ bool LLAudioData::load()
{
// No free buffers, abort.
LL_INFOS() << "Not able to allocate a new audio buffer, aborting." << LL_ENDL;
+ // *TODO: Mark this failure differently so the audio engine could retry loading this buffer in the future
+ mHasWAVLoadFailed = true;
return true;
}
@@ -1843,7 +1832,8 @@ bool LLAudioData::load()
mID.toString(uuid_str);
wav_path= gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf";
- if (!mBufferp->loadWAV(wav_path))
+ mHasWAVLoadFailed = !mBufferp->loadWAV(wav_path);
+ if (mHasWAVLoadFailed)
{
// Hrm. Right now, let's unset the buffer, since it's empty.
gAudiop->cleanupBuffer(mBufferp);
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index b5fd4c27a1..0fe8b3d756 100644..100755
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -47,8 +47,8 @@ const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f;
const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f;
const F32 DEFAULT_MIN_DISTANCE = 2.0f;
-#define MAX_CHANNELS 30
-#define MAX_BUFFERS 40 // Some extra for preloading, maybe?
+#define LL_MAX_AUDIO_CHANNELS 30
+#define LL_MAX_AUDIO_BUFFERS 40 // Some extra for preloading, maybe?
class LLAudioSource;
class LLAudioData;
@@ -88,7 +88,7 @@ public:
virtual ~LLAudioEngine();
// initialization/startup/shutdown
- virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title);
+ virtual bool init(void *userdata, const std::string &app_title);
virtual std::string getDriverName(bool verbose) = 0;
virtual void shutdown();
@@ -96,7 +96,7 @@ public:
//virtual void processQueue(const LLUUID &sound_guid);
virtual void setListener(LLVector3 pos,LLVector3 vel,LLVector3 up,LLVector3 at);
virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0;
- virtual void idle(F32 max_decode_time = 0.f);
+ virtual void idle();
virtual void updateChannels();
//
@@ -209,7 +209,6 @@ protected:
S32 mLastStatus;
- S32 mNumChannels;
bool mEnableWind;
LLUUID mCurrentTransfer; // Audio file currently being transferred by the system
@@ -224,11 +223,11 @@ protected:
source_map mAllSources;
data_map mAllData;
- LLAudioChannel *mChannels[MAX_CHANNELS];
+ std::array<LLAudioChannel*, LL_MAX_AUDIO_CHANNELS> mChannels;
// Buffers needs to change into a different data structure, as the number of buffers
// that we have active should be limited by RAM usage, not count.
- LLAudioBuffer *mBuffers[MAX_BUFFERS];
+ std::array<LLAudioBuffer*, LL_MAX_AUDIO_BUFFERS> mBuffers;
F32 mMasterGain;
F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true.
@@ -266,8 +265,8 @@ public:
void addAudioData(LLAudioData *adp, bool set_current = TRUE);
- void setAmbient(const bool ambient) { mAmbient = ambient; }
- bool isAmbient() const { return mAmbient; }
+ void setForcedPriority(const bool ambient) { mForcedPriority = ambient; }
+ bool isForcedPriority() const { return mForcedPriority; }
void setLoop(const bool loop) { mLoop = loop; }
bool isLoop() const { return mLoop; }
@@ -326,7 +325,7 @@ protected:
F32 mPriority;
F32 mGain;
bool mSourceMuted;
- bool mAmbient;
+ bool mForcedPriority; // ignore mute, set high priority, researved for sound preview and UI
bool mLoop;
bool mSyncMaster;
bool mSyncSlave;
@@ -360,32 +359,36 @@ protected:
class LLAudioData
{
-public:
- LLAudioData(const LLUUID &uuid);
- bool load();
-
- LLUUID getID() const { return mID; }
- LLAudioBuffer *getBuffer() const { return mBufferp; }
-
- bool hasLocalData() const { return mHasLocalData; }
- bool hasDecodedData() const { return mHasDecodedData; }
- bool hasCompletedDecode() const { return mHasCompletedDecode; }
- bool hasValidData() const { return mHasValidData; }
-
- void setHasLocalData(const bool hld) { mHasLocalData = hld; }
- void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
- void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; }
- void setHasValidData(const bool hvd) { mHasValidData = hvd; }
-
- friend class LLAudioEngine; // Severe laziness, bad.
-
-protected:
- LLUUID mID;
- LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
- bool mHasLocalData; // Set true if the sound asset file is available locally
- bool mHasDecodedData; // Set true if the sound file has been decoded
- bool mHasCompletedDecode; // Set true when the sound is decoded
- bool mHasValidData; // Set false if decoding failed, meaning the sound asset is bad
+ public:
+ LLAudioData(const LLUUID &uuid);
+ bool load();
+
+ LLUUID getID() const { return mID; }
+ LLAudioBuffer *getBuffer() const { return mBufferp; }
+
+ bool hasLocalData() const { return mHasLocalData; }
+ bool hasDecodedData() const { return mHasDecodedData; }
+ bool hasCompletedDecode() const { return mHasCompletedDecode; }
+ bool hasDecodeFailed() const { return mHasDecodeFailed; }
+ bool hasWAVLoadFailed() const { return mHasWAVLoadFailed; }
+
+ void setHasLocalData(const bool hld) { mHasLocalData = hld; }
+ void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
+ void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; }
+ void setHasDecodeFailed(const bool hdf) { mHasDecodeFailed = hdf; }
+ void setHasWAVLoadFailed(const bool hwlf) { mHasWAVLoadFailed = hwlf; }
+
+ friend class LLAudioEngine; // Severe laziness, bad.
+
+ protected:
+ LLUUID mID;
+ LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
+ bool mHasLocalData; // Set true if the encoded sound asset file is available locally
+ bool mHasDecodedData; // Set true if the decoded sound file is available on disk
+ bool mHasCompletedDecode; // Set true when the sound is decoded
+ bool mHasDecodeFailed; // Set true if decoding failed, meaning the sound asset is bad
+ bool mHasWAVLoadFailed; // Set true if loading the decoded WAV file failed, meaning the sound asset should be decoded instead if
+ // possible
};
diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp
index b0c87b0208..ba743020b5 100644
--- a/indra/llaudio/llaudioengine_fmodstudio.cpp
+++ b/indra/llaudio/llaudioengine_fmodstudio.cpp
@@ -74,7 +74,7 @@ static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
return true;
}
-bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, const std::string &app_title)
+bool LLAudioEngine_FMODSTUDIO::init(void* userdata, const std::string &app_title)
{
U32 version;
FMOD_RESULT result;
@@ -86,7 +86,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
return false;
//will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer.
- LLAudioEngine::init(num_channels, userdata, app_title);
+ LLAudioEngine::init(userdata, app_title);
result = mSystem->getVersion(&version);
Check_FMOD_Error(result, "FMOD::System::getVersion");
@@ -98,7 +98,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
}
// In this case, all sounds, PLUS wind and stream will be software.
- result = mSystem->setSoftwareChannels(num_channels + 2);
+ result = mSystem->setSoftwareChannels(LL_MAX_AUDIO_CHANNELS + 2);
Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels");
FMOD_ADVANCEDSETTINGS settings;
@@ -127,7 +127,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
{
LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
if (mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
- (result = mSystem->init(num_channels + 2, fmod_flags, const_cast<char*>(app_title.c_str()))) == FMOD_OK)
+ (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, const_cast<char*>(app_title.c_str()))) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
audio_ok = true;
@@ -149,7 +149,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
{
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
if (mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
- (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
+ (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
audio_ok = true;
@@ -190,7 +190,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
// initialize the FMOD engine
// number of channel in this case looks to be identiacal to number of max simultaneously
// playing objects and we can set practically any number
- result = mSystem->init(num_channels + 2, fmod_flags, 0);
+ result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0);
if (Check_FMOD_Error(result, "Error initializing FMOD Studio with default settins, retrying with other format"))
{
result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0/*- ignore*/);
@@ -198,7 +198,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
{
return false;
}
- result = mSystem->init(num_channels + 2, fmod_flags, 0);
+ result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0);
}
if (Check_FMOD_Error(result, "Error initializing FMOD Studio"))
{
@@ -519,9 +519,9 @@ void LLAudioChannelFMODSTUDIO::update3DPosition()
return;
}
- if (mCurrentSourcep->isAmbient())
+ if (mCurrentSourcep->isForcedPriority())
{
- // Ambient sound, don't need to do any positional updates.
+ // Prioritized UI and preview sounds don't need to do any positional updates.
set3DMode(false);
}
else
diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h
index f2361df1b6..d3d6d69685 100644
--- a/indra/llaudio/llaudioengine_fmodstudio.h
+++ b/indra/llaudio/llaudioengine_fmodstudio.h
@@ -51,7 +51,7 @@ public:
virtual ~LLAudioEngine_FMODSTUDIO();
// initialization/startup/shutdown
- virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title);
+ virtual bool init(void *user_data, const std::string &app_title);
virtual std::string getDriverName(bool verbose);
virtual void allocateListener();
diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp
index 3bdd0302ee..0a79614424 100644
--- a/indra/llaudio/llaudioengine_openal.cpp
+++ b/indra/llaudio/llaudioengine_openal.cpp
@@ -52,10 +52,10 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
}
// virtual
-bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title)
+bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title)
{
mWindGen = NULL;
- LLAudioEngine::init(num_channels, userdata, app_title);
+ LLAudioEngine::init(userdata, app_title);
if(!alutInit(NULL, NULL))
{
@@ -297,7 +297,7 @@ void LLAudioChannelOpenAL::update3DPosition()
{
return;
}
- if (mCurrentSourcep->isAmbient())
+ if (mCurrentSourcep->isForcedPriority())
{
alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h
index 366f9259e3..a3cab97cd2 100644
--- a/indra/llaudio/llaudioengine_openal.h
+++ b/indra/llaudio/llaudioengine_openal.h
@@ -40,7 +40,7 @@ class LLAudioEngine_OpenAL : public LLAudioEngine
LLAudioEngine_OpenAL();
virtual ~LLAudioEngine_OpenAL();
- virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title);
+ virtual bool init(void *user_data, const std::string &app_title);
virtual std::string getDriverName(bool verbose);
virtual void allocateListener();
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
index 1ad29a3f59..85577992a6 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
@@ -70,7 +70,11 @@ mRetryCount(0)
// Must be larger than the usual Second Life frame stutter time.
const U32 buffer_seconds = 10; //sec
const U32 estimated_bitrate = 128; //kbit/sec
- mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
+ FMOD_RESULT result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
+ }
// Here's where we set the size of the network buffer and some buffering
// parameters. In this case we want a network buffer of 16k, we want it
@@ -134,7 +138,7 @@ void LLStreamingAudio_FMODSTUDIO::killDeadStreams()
{
LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL;
delete streamp;
- mDeadStreams.erase(iter++);
+ iter = mDeadStreams.erase(iter);
}
else
{
@@ -404,7 +408,11 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
if (mStreamChannel)
return mStreamChannel; //Already have a channel for this stream.
- mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
+ FMOD_RESULT result = mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL;
+ }
return mStreamChannel;
}
@@ -445,16 +453,29 @@ bool LLAudioStreamManagerFMODSTUDIO::stopStream()
FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
{
FMOD_OPENSTATE state;
- mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
+ FMOD_RESULT result = mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL;
+ }
return state;
}
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
- mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
+ FMOD_RESULT result = mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
+ return;
+ }
FMOD_ADVANCEDSETTINGS settings;
memset(&settings, 0, sizeof(settings));
settings.cbSize = sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
- mSystem->setAdvancedSettings(&settings);
+ result = mSystem->setAdvancedSettings(&settings);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setAdvancedSettings error: " << FMOD_ErrorString(result) << LL_ENDL;
+ }
}
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index e906d81ce1..c38614b0b4 100644
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -44,6 +44,14 @@ using namespace std;
#define INCHES_TO_METERS 0.02540005f
+/// The .bvh does not have a formal spec, and different readers interpret things in their own way.
+/// In OUR usage, frame 0 is used in optimization and is not considered to be part of the animation.
+const S32 NUMBER_OF_IGNORED_FRAMES_AT_START = 1;
+/// In our usage, the last frame is used only to indicate what the penultimate frame should be interpolated towards.
+/// I.e., the animation only plays up to the start of the last frame. There is no hold or exptrapolation past that point..
+/// Thus there are two frame of the total that do not contribute to the total running time of the animation.
+const S32 NUMBER_OF_UNPLAYED_FRAMES = NUMBER_OF_IGNORED_FRAMES_AT_START + 1;
+
const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f;
const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f;
@@ -865,7 +873,10 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &
return E_ST_NO_FRAME_TIME;
}
- mDuration = (F32)mNumFrames * mFrameTime;
+ // If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime.
+ // If the user supples exactly one total frame, it isn't clear if that is a pose or reference frame, and the
+ // behavior is not defined. In this case, retain historical undefined behavior.
+ mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime;
if (!mLoop)
{
mLoopOutPoint = mDuration;
@@ -1355,12 +1366,13 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );
S32 outcount = 0;
- S32 frame = 1;
+ S32 frame = 0;
for ( ki = joint->mKeys.begin();
ki != joint->mKeys.end();
++ki )
{
- if ((frame == 1) && joint->mRelativeRotationKey)
+
+ if ((frame == 0) && joint->mRelativeRotationKey)
{
first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
@@ -1373,7 +1385,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
continue;
}
- time = (F32)frame * mFrameTime;
+ time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts.
if (mergeParent)
{
@@ -1433,12 +1445,12 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
LLVector3 relPos = joint->mRelativePosition;
LLVector3 relKey;
- frame = 1;
+ frame = 0;
for ( ki = joint->mKeys.begin();
ki != joint->mKeys.end();
++ki )
{
- if ((frame == 1) && joint->mRelativePositionKey)
+ if ((frame == 0) && joint->mRelativePositionKey)
{
relKey.setVec(ki->mPos);
}
@@ -1449,7 +1461,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
continue;
}
- time = (F32)frame * mFrameTime;
+ time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts.
LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot;
LLVector3 outPos = inPos * frameRot * offsetRot;
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index a25ff16786..ebf7454a61 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -1222,8 +1222,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
//-----------------------------------------------------------------------------
// deserialize()
+//
+// allow_invalid_joints should be true when handling existing content, to avoid breakage.
+// During upload, we should be more restrictive and reject such animations.
//-----------------------------------------------------------------------------
-BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
+BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints)
{
BOOL old_version = FALSE;
mJointMotionList = new LLKeyframeMotion::JointMotionList;
@@ -1344,6 +1347,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
return FALSE;
}
+ //SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside
+ LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e");
+ LLUUID const formal_female_land_anim("6a9a173b-61fa-3ad5-01fa-a851cfc5f66a");
+ if (female_land_anim == asset_id || formal_female_land_anim == asset_id)
+ {
+ LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL;
+ mJointMotionList->mLoop = FALSE;
+ }
+
//-------------------------------------------------------------------------
// get easeIn and easeOut
//-------------------------------------------------------------------------
@@ -1443,6 +1455,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
if (joint)
{
S32 joint_num = joint->getJointNum();
+ joint_name = joint->getName(); // canonical name in case this is an alias.
// LL_INFOS() << " joint: " << joint_name << LL_ENDL;
if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0))
{
@@ -1457,7 +1470,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
{
LL_WARNS() << "invalid joint name: " << joint_name
<< " for animation " << asset_id << LL_ENDL;
- //return FALSE;
+ if (!allow_invalid_joints)
+ {
+ return FALSE;
+ }
}
joint_motion->mJointName = joint_name;
@@ -2096,8 +2112,9 @@ U32 LLKeyframeMotion::getFileSize()
//-----------------------------------------------------------------------------
// dumpToFile()
//-----------------------------------------------------------------------------
-void LLKeyframeMotion::dumpToFile(const std::string& name)
+bool LLKeyframeMotion::dumpToFile(const std::string& name)
{
+ bool succ = false;
if (isLoaded())
{
std::string outfile_base;
@@ -2114,10 +2131,24 @@ void LLKeyframeMotion::dumpToFile(const std::string& name)
const LLUUID& id = getID();
outfile_base = id.asString();
}
- std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim");
+
+ if (gDirUtilp->getExtension(outfile_base).empty())
+ {
+ outfile_base += ".anim";
+ }
+ std::string outfilename;
+ if (gDirUtilp->getDirName(outfile_base).empty())
+ {
+ outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base);
+ }
+ else
+ {
+ outfilename = outfile_base;
+ }
if (LLFile::isfile(outfilename))
{
- return;
+ LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL;
+ return false;
}
S32 file_size = getFileSize();
@@ -2131,11 +2162,13 @@ void LLKeyframeMotion::dumpToFile(const std::string& name)
outfile.open(outfilename, LL_APR_WPB);
if (outfile.getFileHandle())
{
- outfile.write(buffer, file_size);
+ S32 wrote_bytes = outfile.write(buffer, file_size);
+ succ = (wrote_bytes == file_size);
}
}
delete [] buffer;
}
+ return succ;
}
//-----------------------------------------------------------------------------
diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h
index 9a927ede9a..96746f57c9 100644
--- a/indra/llcharacter/llkeyframemotion.h
+++ b/indra/llcharacter/llkeyframemotion.h
@@ -156,9 +156,9 @@ public:
public:
U32 getFileSize();
BOOL serialize(LLDataPacker& dp) const;
- BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id);
+ BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true);
BOOL isLoaded() { return mJointMotionList != NULL; }
- void dumpToFile(const std::string& name);
+ bool dumpToFile(const std::string& name);
// setters for modifying a keyframe animation
@@ -432,6 +432,9 @@ protected:
F32 mLastUpdateTime;
F32 mLastLoopedTime;
AssetStatus mAssetStatus;
+
+public:
+ void setCharacter(LLCharacter* character) { mCharacter = character; }
};
class LLKeyframeDataCache
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 4dbf1282c4..21998f0b78 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -10,7 +10,7 @@ include(Boost)
include(LLSharedLibs)
include(JsonCpp)
include(Copy3rdPartyLibs)
-include(ZLIB)
+include(ZLIBNG)
include(URIPARSER)
include(Tracy)
@@ -18,7 +18,7 @@ include_directories(
${EXPAT_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
${JSONCPP_INCLUDE_DIR}
- ${ZLIB_INCLUDE_DIRS}
+ ${ZLIBNG_INCLUDE_DIRS}
${URIPARSER_INCLUDE_DIRS}
${TRACY_INCLUDE_DIR}
)
@@ -130,6 +130,7 @@ set(llcommon_HEADER_FILES
CMakeLists.txt
chrono.h
+ classic_callback.h
commoncontrol.h
ctype_workaround.h
fix_macros.h
@@ -267,6 +268,11 @@ set(llcommon_HEADER_FILES
workqueue.h
StackWalker.h
)
+
+if (DARWIN)
+ list(APPEND llcommon_HEADER_FILES llsys_objc.h)
+ list(APPEND llcommon_SOURCE_FILES llsys_objc.mm)
+endif (DARWIN)
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
@@ -302,7 +308,7 @@ target_link_libraries(
${APR_LIBRARIES}
${EXPAT_LIBRARIES}
${JSONCPP_LIBRARIES}
- ${ZLIB_LIBRARIES}
+ ${ZLIBNG_LIBRARIES}
${WINDOWS_LIBRARIES}
${BOOST_FIBER_LIBRARY}
${BOOST_CONTEXT_LIBRARY}
@@ -314,12 +320,6 @@ target_link_libraries(
${TRACY_LIBRARY}
)
-if (DARWIN)
- include(CMakeFindFrameworks)
- find_library(CARBON_LIBRARY Carbon)
- target_link_libraries(llcommon ${CARBON_LIBRARY})
-endif (DARWIN)
-
add_dependencies(llcommon stage_third_party_libs)
if (LL_TESTS)
@@ -338,16 +338,17 @@ if (LL_TESTS)
${BOOST_CONTEXT_LIBRARY}
${BOOST_THREAD_LIBRARY}
${BOOST_SYSTEM_LIBRARY})
- LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(classic_callback "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llbase64 "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llcond "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldate "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldeadmantimer "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldependencies "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventfilter "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}")
@@ -365,8 +366,8 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltrace "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(threadsafeschedule "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(tuple "" "${test_libs}")
diff --git a/indra/llcommon/classic_callback.cpp b/indra/llcommon/classic_callback.cpp
new file mode 100644
index 0000000000..5674e0a44d
--- /dev/null
+++ b/indra/llcommon/classic_callback.cpp
@@ -0,0 +1,16 @@
+/**
+ * @file classic_callback.cpp
+ * @author Nat Goodspeed
+ * @date 2021-09-23
+ * @brief Implementation for classic_callback.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+namespace {
+
+const char dummy[] = "cpp file required to build test program";
+
+} // anonymous namespace
diff --git a/indra/llcommon/classic_callback.h b/indra/llcommon/classic_callback.h
new file mode 100644
index 0000000000..1ad6dbc58f
--- /dev/null
+++ b/indra/llcommon/classic_callback.h
@@ -0,0 +1,292 @@
+/**
+ * @file classic_callback.h
+ * @author Nat Goodspeed
+ * @date 2016-06-21
+ * @brief ClassicCallback and HeapClassicCallback
+ *
+ * This header file addresses the problem of passing a method on a C++ object
+ * to an API that requires a classic-C function pointer. Typically such a
+ * callback API accepts a void* pointer along with the function pointer, and
+ * the function pointer signature accepts a void* parameter. The API passes
+ * the caller's pointer value into the callback function so it can find its
+ * data. In C++, there are a few ways to deal with this case:
+ *
+ * - Use a static method with correct signature. If you don't need access to a
+ * specific instance, that works fine.
+ * - Store the object statically (or store a static pointer to a non-static
+ * instance). As long as you only care about one instance, that works, but
+ * starts to get a little icky. As soon as there's more than one pertinent
+ * instance, fight valiantly against the temptation to stuff the instance
+ * pointer into a static pointer variable "just for a moment."
+ * - Code a static trampoline callback function that accepts the void* user
+ * data pointer, casts it to the appropriate class type and calls the actual
+ * method on that class.
+ *
+ * ClassicCallback encapsulates the last. You need only construct a
+ * ClassicCallback instance somewhere that will survive until the callback is
+ * called, binding the target C++ callable. You then call its get_callback()
+ * and get_userdata() methods to pass an appropriate classic-C function
+ * pointer and void* user data pointer, respectively, to the old-style
+ * callback API. get_callback() synthesizes a static trampoline function
+ * that casts the user data pointer and calls the bound C++ callable.
+ *
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_CLASSIC_CALLBACK_H)
+#define LL_CLASSIC_CALLBACK_H
+
+#include <tuple>
+#include <type_traits> // std::is_same
+
+/*****************************************************************************
+* Helpers
+*****************************************************************************/
+
+// find a type in a parameter pack: http://stackoverflow.com/q/17844867/5533635
+// usage: index_of<0, sought_t, PackName...>::value
+template <int idx, typename sought, typename candidate, typename ...rest>
+struct index_of
+{
+ static constexpr int const value =
+ std::is_same<sought, candidate>::value ?
+ idx : index_of<idx + 1, sought, rest...>::value;
+};
+
+// recursion tail
+template <int idx, typename sought, typename candidate>
+struct index_of<idx, sought, candidate>
+{
+ static constexpr int const value =
+ std::is_same<sought, candidate>::value ? idx : -1;
+};
+
+/*****************************************************************************
+* ClassicCallback
+*****************************************************************************/
+/**
+ * Instantiate ClassicCallback in whatever storage will persist long enough
+ * for the callback to be called. It holds a modern C++ callable, providing a
+ * static function pointer and a USERDATA (default void*) capable of being
+ * passed through a classic-C callback API. When the static function is called
+ * with that USERDATA pointer, ClassicCallback forwards the call to the bound
+ * C++ callable.
+ *
+ * Usage:
+ * @code
+ * // callback signature required by the API of interest
+ * typedef void (*callback_t)(int, const char*, void*, double);
+ * // old-style API that accepts a classic-C callback function pointer
+ * void oldAPI(callback_t callback, void* userdata);
+ * // but I want to pass a lambda that references data local to my function!
+ * // (We don't need to name the void* parameter in the C++ callable;
+ * // ClassicCallback already used it to locate the lambda instance.)
+ * auto ccb{
+ * makeClassicCallback<callback_t>(
+ * [=](int n, const char* s, void*, double f){ ... }) };
+ * oldAPI(ccb.get_callback(), ccb.get_userdata());
+ * // If the passed callback is called before oldAPI() returns, we can now
+ * // safely destroy ccb. If the callback might be called later, consider
+ * // HeapClassicCallback instead.
+ * @endcode
+ *
+ * If you have a callable object in hand, and you want to pass that to
+ * ClassicCallback, you may either consume it by passing std::move(object), or
+ * explicitly specify a reference to that object type as the CALLABLE template
+ * parameter:
+ * @code
+ * CallableObject obj;
+ * ClassicCallback<callback_t, void*, CallableObject&> ccb{obj};
+ * @endcode
+ */
+// CALLABLE should either be deduced, e.g. by makeClassicCallback(), or
+// specified explicitly. Its default type is meaningless, coded only so we can
+// provide a useful default for USERDATA.
+template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
+class ClassicCallback
+{
+ typedef ClassicCallback<SIGNATURE, USERDATA, CALLABLE> self_t;
+
+public:
+ /// ClassicCallback binds any modern C++ callable.
+ ClassicCallback(CALLABLE&& callable):
+ mCallable(std::forward<CALLABLE>(callable))
+ {}
+
+ /**
+ * ClassicCallback must not itself be copied or moved! Once you've passed
+ * get_userdata() to some API, this object MUST remain at that address.
+ */
+ // However, we can't yet count on C++17 Class Template Argument Deduction,
+ // which means makeClassicCallback() is still useful, which means we MUST
+ // be able to return one to construct into caller's instance (move ctor).
+ // Possible defense: bool 'referenced' data member set by get_userdata(),
+ // with an llassert_always(! referenced) check in the move constructor.
+ ClassicCallback(ClassicCallback const&) = delete;
+ ClassicCallback(ClassicCallback&&) = default; // delete;
+ ClassicCallback& operator=(ClassicCallback const&) = delete;
+ ClassicCallback& operator=(ClassicCallback&&) = delete;
+
+ /// Call get_callback() to get the necessary function pointer.
+ SIGNATURE get_callback() const
+ {
+ // This declaration is where the compiler instantiates the correct
+ // signature for the call() function template.
+ SIGNATURE callback = call;
+ return callback;
+ }
+
+ /// Call get_userdata() to get the opaque USERDATA pointer to pass
+ /// through the classic-C callback API.
+ USERDATA get_userdata() const
+ {
+ // The USERDATA userdata is of course a pointer to this object.
+ return static_cast<USERDATA>(const_cast<self_t*>(this));
+ }
+
+protected:
+ /**
+ * This call() method accepts one or more callback arguments. It assumes
+ * the first USERDATA parameter is the userdata.
+ */
+ // Note that we're not literally using C++ perfect forwarding here -- it
+ // doesn't work to specify (Args&&... args). But that's okay because we're
+ // dealing with a classic-C callback! It's not going to pass any move-only
+ // types.
+ template <typename... Args>
+ static auto call(Args... args)
+ {
+ auto userdata = extract_userdata(std::forward<Args>(args)...);
+ // cast the userdata param to 'this' and call mCallable
+ return static_cast<self_t*>(userdata)->
+ mCallable(std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static USERDATA extract_userdata(Args... args)
+ {
+ // Search for the first USERDATA parameter type, then extract that pointer.
+ // extract value from parameter pack: http://stackoverflow.com/a/24710433/5533635
+ return std::get<index_of<0, USERDATA, Args...>::value>(std::forward_as_tuple(args...));
+ }
+
+ CALLABLE mCallable;
+};
+
+/**
+ * Usage:
+ * @code
+ * auto ccb{ makeClassicCallback<classic_callback_signature>(actual_callback) };
+ * @endcode
+ */
+template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
+auto makeClassicCallback(CALLABLE&& callable)
+{
+ return std::move(ClassicCallback<SIGNATURE, USERDATA, CALLABLE>
+ (std::forward<CALLABLE>(callable)));
+}
+
+/*****************************************************************************
+* HeapClassicCallback
+*****************************************************************************/
+/**
+ * HeapClassicCallback is like ClassicCallback, with this exception: it MUST
+ * be allocated on the heap because, once the callback has been called, it
+ * deletes itself. This addresses the problem of a callback whose lifespan
+ * must persist beyond the scope in which the callback API is engaged -- but
+ * naturally this callback must be called exactly ONCE.
+ *
+ * Usage:
+ * @code
+ * // callback signature required by the API of interest
+ * typedef void (*callback_t)(int, const char*, void*, double);
+ * // here's the old-style API
+ * void oldAPI(callback_t callback, void* userdata);
+ * // want to call someObjPtr->method() when oldAPI() fires the callback,
+ * // sometime in the future after the enclosing function has returned
+ * auto ccb{
+ * makeHeapClassicCallback<callback_t>(
+ * [someObjPtr](int n, const char* s, void*, double f)
+ * { someObjPtr->method(); }) };
+ * oldAPI(ccb.get_callback(), ccb.get_userdata());
+ * // We don't need a smart pointer for ccb, because it will be deleted once
+ * // oldAPI() calls the bound lambda. HeapClassicCallback is for when the
+ * // callback will be called exactly once. If the classic API might call the
+ * // passed callback more than once -- or might never call it at all --
+ * // manually construct a ClassicCallback on the heap and manage its lifespan
+ * // explicitly.
+ * @endcode
+ */
+template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
+class HeapClassicCallback: public ClassicCallback<SIGNATURE, USERDATA, CALLABLE>
+{
+ typedef ClassicCallback<SIGNATURE, USERDATA, CALLABLE> super;
+ typedef HeapClassicCallback<SIGNATURE, USERDATA, CALLABLE> self_t;
+
+ // This destructor is intentionally private to prevent allocation anywhere
+ // but the heap. (The Design and Evolution of C++, section 11.4.2: Control
+ // of Allocation)
+ ~HeapClassicCallback() {}
+
+public:
+ HeapClassicCallback(CALLABLE&& callable):
+ super(std::forward<CALLABLE>(callable))
+ {}
+
+ // makeHeapClassicCallback() only needs to return a pointer -- not an
+ // instance -- so we can lock down our move constructor too.
+ HeapClassicCallback(HeapClassicCallback&&) = delete;
+
+ /// Replicate get_callback() from the base class because we must
+ /// instantiate OUR call() function template.
+ SIGNATURE get_callback() const
+ {
+ // This declaration is where the compiler instantiates the correct
+ // signature for the call() function template.
+ SIGNATURE callback = call;
+ return callback;
+ }
+
+ /// Replicate get_userdata() from the base class because our call()
+ /// method must be able to reconstitute a pointer to this subclass.
+ USERDATA get_userdata() const
+ {
+ // The USERDATA userdata is of course a pointer to this object.
+ return static_cast<const USERDATA>(const_cast<self_t*>(this));
+ }
+
+private:
+ // call() uses a helper class to delete the HeapClassicCallback when done,
+ // for two reasons. Most importantly, this deletes even if the callback
+ // throws an exception. But also, call() must directly return the callback
+ // result for return-type deduction.
+ struct Destroyer
+ {
+ Destroyer(self_t* p): mPtr(p) {}
+ ~Destroyer() { delete mPtr; }
+
+ self_t* mPtr;
+ };
+
+ template <typename... Args>
+ static auto call(Args... args)
+ {
+ // extract userdata at this level too
+ USERDATA userdata = super::extract_userdata(std::forward<Args>(args)...);
+ // arrange to delete it when we leave by whatever means
+ Destroyer destroy(static_cast<self_t*>(userdata));
+
+ return super::call(std::forward<Args>(args)...);
+ }
+};
+
+template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
+auto makeHeapClassicCallback(CALLABLE&& callable)
+{
+ return new HeapClassicCallback<SIGNATURE, USERDATA, CALLABLE>
+ (std::forward<CALLABLE>(callable));
+}
+
+#endif /* ! defined(LL_CLASSIC_CALLBACK_H) */
diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h
index b68e9e0f82..da9d98c16c 100644
--- a/indra/llcommon/llalignedarray.h
+++ b/indra/llcommon/llalignedarray.h
@@ -116,14 +116,20 @@ void LLAlignedArray<T, alignment>::resize(U32 size)
template <class T, U32 alignment>
T& LLAlignedArray<T, alignment>::operator[](int idx)
{
- llassert(idx < mElementCount);
+ if(idx >= mElementCount || idx < 0)
+ {
+ LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL;
+ }
return mArray[idx];
}
template <class T, U32 alignment>
const T& LLAlignedArray<T, alignment>::operator[](int idx) const
{
- llassert(idx < mElementCount);
+ if (idx >= mElementCount || idx < 0)
+ {
+ LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL;
+ }
return mArray[idx];
}
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index e6cc06e8d0..f08cc18036 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -96,6 +96,7 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, true));
+ addEntry(LLAssetType::AT_MATERIAL, new AssetEntry("MATERIAL", "material", "render material", true, true, true));
addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 652c548d59..e8df8574f7 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -127,8 +127,9 @@ public:
AT_RESERVED_6 = 55,
AT_SETTINGS = 56, // Collection of settings
-
- AT_COUNT = 57,
+ AT_MATERIAL = 57, // Render Material
+
+ AT_COUNT = 58,
// +*********************************************************+
// | TO ADD AN ELEMENT TO THIS ENUM: |
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index c2d353b0fc..14bfb98629 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -35,6 +35,7 @@
// STL headers
// std headers
#include <atomic>
+#include <stdexcept>
// external library headers
#include <boost/bind.hpp>
#include <boost/fiber/fiber.hpp>
@@ -214,6 +215,22 @@ std::string LLCoros::logname()
return data.mName.empty()? data.getKey() : data.mName;
}
+void LLCoros::saveException(const std::string& name, std::exception_ptr exc)
+{
+ mExceptionQueue.emplace(name, exc);
+}
+
+void LLCoros::rethrow()
+{
+ if (! mExceptionQueue.empty())
+ {
+ ExceptionData front = mExceptionQueue.front();
+ mExceptionQueue.pop();
+ LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL;
+ std::rethrow_exception(front.exception);
+ }
+}
+
void LLCoros::setStackSize(S32 stacksize)
{
LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL;
@@ -302,11 +319,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
}
}
-void LLCoros::winlevel(const std::string& name, const callable_t& callable)
+void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)
{
__try
{
- toplevelTryWrapper(name, callable);
+ LLCoros::toplevelTryWrapper(name, callable);
}
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
{
@@ -321,7 +338,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable)
throw std::exception(integer_string);
}
}
-
#endif
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
@@ -350,11 +366,19 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
}
catch (...)
{
+#if LL_WINDOWS
// Any OTHER kind of uncaught exception will cause the viewer to
- // crash, hopefully informatively.
+ // crash, SEH handling should catch it and report to bugsplat.
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
+#else
+ // Stash any OTHER kind of uncaught exception in the rethrow() queue
+ // to be rethrown by the main fiber.
+ LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
+ << name << LL_ENDL;
+ LLCoros::instance().saveException(name, std::current_exception());
+#endif
}
}
@@ -364,8 +388,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
- // Can not use __try in functions that require unwinding, so use one more wrapper
- winlevel(name, callable);
+ // Because SEH can's have unwinding, need to call a wrapper
+ // 'try' is inside SEH handling to not catch LLContinue
+ sehHandle(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index a94cfca19f..dbff921f16 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -38,6 +38,8 @@
#include "llinstancetracker.h"
#include <boost/function.hpp>
#include <string>
+#include <exception>
+#include <queue>
// e.g. #include LLCOROS_MUTEX_HEADER
#define LLCOROS_MUTEX_HEADER <boost/fiber/mutex.hpp>
@@ -156,6 +158,19 @@ public:
* LLCoros::launch()).
*/
static std::string getName();
+
+ /**
+ * rethrow() is called by the thread's main fiber to propagate an
+ * exception from any coroutine into the main fiber, where it can engage
+ * the normal unhandled-exception machinery, up to and including crash
+ * reporting.
+ *
+ * LLCoros maintains a queue of otherwise-uncaught exceptions from
+ * terminated coroutines. Each call to rethrow() pops the first of those
+ * and rethrows it. When the queue is empty (normal case), rethrow() is a
+ * no-op.
+ */
+ void rethrow();
/**
* This variation returns a name suitable for log messages: the explicit
@@ -292,13 +307,27 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
+ void toplevelTryWrapper(const std::string& name, const callable_t& callable);
#if LL_WINDOWS
- void winlevel(const std::string& name, const callable_t& callable);
+ void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper
#endif
- void toplevelTryWrapper(const std::string& name, const callable_t& callable);
- void toplevel(std::string name, callable_t callable);
+ void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper
struct CoroData;
static CoroData& get_CoroData(const std::string& caller);
+ void saveException(const std::string& name, std::exception_ptr exc);
+
+ struct ExceptionData
+ {
+ ExceptionData(const std::string& nm, std::exception_ptr exc):
+ name(nm),
+ exception(exc)
+ {}
+ // name of coroutine that originally threw this exception
+ std::string name;
+ // the thrown exception
+ std::exception_ptr exception;
+ };
+ std::queue<ExceptionData> mExceptionQueue;
S32 mStackSize;
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 749b66b472..7cdf7254ff 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -257,11 +257,9 @@ U64 LLMemory::getCurrentRSS()
mach_msg_type_number_t basicInfoCount = MACH_TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
{
-// residentSize = basicInfo.resident_size;
- // Although this method is defined to return the "resident set size,"
- // in fact what callers want from it is the total virtual memory
- // consumed by the application.
- residentSize = basicInfo.virtual_size;
+ residentSize = basicInfo.resident_size;
+ // 64-bit macos apps allocate 32 GB or more at startup, and this is reflected in virtual_size.
+ // basicInfo.virtual_size is not what we want.
}
else
{
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 818df07bb2..4a1a81f083 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -118,7 +118,11 @@ namespace
eMONTIOR_MWAIT=33,
eCPLDebugStore=34,
eThermalMonitor2=35,
- eAltivec=36
+ eAltivec=36,
+ eSSE3S_Features = 37,
+ eSSE4_1_Features = 38,
+ eSSE4_2_Features = 39,
+ eSSE4a_Features = 40,
};
const char* cpu_feature_names[] =
@@ -161,7 +165,11 @@ namespace
"CPL Qualified Debug Store",
"Thermal Monitor 2",
- "Altivec"
+ "Altivec",
+ "SSE3S Instructions",
+ "SSE4.1 Instructions",
+ "SSE4.2 Instructions",
+ "SSE4a Instructions",
};
std::string intel_CPUFamilyName(int composed_family)
@@ -250,6 +258,31 @@ public:
return hasExtension(cpu_feature_names[eSSE2_Ext]);
}
+ bool hasSSE3() const
+ {
+ return hasExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ bool hasSSE3S() const
+ {
+ return hasExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ bool hasSSE41() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ bool hasSSE42() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ bool hasSSE4a() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+
bool hasAltivec() const
{
return hasExtension("Altivec");
@@ -473,6 +506,12 @@ private:
*((int*)(cpu_vendor+4)) = cpu_info[3];
*((int*)(cpu_vendor+8)) = cpu_info[2];
setInfo(eVendor, cpu_vendor);
+ std::string cmp_vendor(cpu_vendor);
+ bool is_amd = false;
+ if (cmp_vendor == "AuthenticAMD")
+ {
+ is_amd = true;
+ }
// Get the information associated with each valid Id
for(unsigned int i=0; i<=ids; ++i)
@@ -504,6 +543,7 @@ private:
if(cpu_info[2] & 0x8)
{
+ // intel specific SSE3 suplements
setExtension(cpu_feature_names[eMONTIOR_MWAIT]);
}
@@ -516,7 +556,22 @@ private:
{
setExtension(cpu_feature_names[eThermalMonitor2]);
}
-
+
+ if (cpu_info[2] & 0x200)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (cpu_info[2] & 0x80000)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (cpu_info[2] & 0x100000)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
unsigned int feature_info = (unsigned int) cpu_info[3];
for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)
{
@@ -543,8 +598,17 @@ private:
__cpuid(cpu_info, i);
// Interpret CPU brand string and cache information.
- if (i == 0x80000002)
- memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+ if (i == 0x80000001)
+ {
+ if (is_amd)
+ {
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+ }
+ else if (i == 0x80000002)
+ {
+ memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+ }
else if (i == 0x80000003)
memcpy(cpu_brand_string + 16, cpu_info, sizeof(cpu_info));
else if (i == 0x80000004)
@@ -690,6 +754,41 @@ private:
uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits");
S32 *ext_feature_infos = (S32*)(&ext_feature_info);
setConfig(eExtFeatureBits, ext_feature_infos[0]);
+
+
+ char cpu_features[1024];
+ len = sizeof(cpu_features);
+ memset(cpu_features, 0, len);
+ sysctlbyname("machdep.cpu.features", (void*)cpu_features, &len, NULL, 0);
+
+ std::string cpu_features_str(cpu_features);
+ cpu_features_str = " " + cpu_features_str + " ";
+
+ if (cpu_features_str.find(" SSE3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ if (cpu_features_str.find(" SSSE3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4.1 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4.2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4A ") != std::string::npos)
+ {
+ // Not supposed to happen?
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
}
};
@@ -800,6 +899,31 @@ private:
{
setExtension(cpu_feature_names[eSSE2_Ext]);
}
+
+ if (flags.find(" pni ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ if (flags.find(" ssse3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (flags.find(" sse4_1 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (flags.find(" sse4_2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ if (flags.find(" sse4a ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
# endif // LL_X86
}
@@ -860,6 +984,11 @@ LLProcessorInfo::~LLProcessorInfo() {}
F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
+bool LLProcessorInfo::hasSSE3() const { return mImpl->hasSSE3(); }
+bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); }
+bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); }
+bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); }
+bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); }
std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index b77eb22c3a..1a473ddc97 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -54,6 +54,11 @@ public:
F64MegahertzImplicit getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
+ bool hasSSE3() const;
+ bool hasSSE3S() const;
+ bool hasSSE41() const;
+ bool hasSSE42() const;
+ bool hasSSE4a() const;
bool hasAltivec() const;
std::string getCPUFamilyName() const;
std::string getCPUBrandName() const;
diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h
index 7a593092da..ac20209062 100644
--- a/indra/llcommon/llprofiler.h
+++ b/indra/llcommon/llprofiler.h
@@ -86,8 +86,8 @@ extern thread_local bool gProfilerEnabled;
#define TRACY_ONLY_IPV4 1
#include "Tracy.hpp"
- // Mutually exclusive with detailed memory tracing
- #define LL_PROFILER_ENABLE_TRACY_OPENGL 0
+ // Disable memory tracing when enabled, but enabled
+ #define LL_PROFILER_ENABLE_TRACY_OPENGL 1
#endif
#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY
@@ -104,8 +104,6 @@ extern thread_local bool gProfilerEnabled;
#define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow
#define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan
#define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red
- #define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size)
- #define LL_PROFILE_FREE(ptr) TracyFree(ptr)
#endif
#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER
#define LL_PROFILER_FRAME_END
@@ -121,8 +119,6 @@ extern thread_local bool gProfilerEnabled;
#define LL_PROFILE_ZONE_ERR(name) (void)(name); // Not supported
#define LL_PROFILE_ZONE_INFO(name) (void)(name); // Not supported
#define LL_PROFILE_ZONE_WARN(name) (void)(name); // Not supported
- #define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size);
- #define LL_PROFILE_FREE(ptr) (void)(ptr);
#endif
#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER
#define LL_PROFILER_FRAME_END FrameMark
@@ -148,6 +144,35 @@ extern thread_local bool gProfilerEnabled;
#define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name)
#endif // LL_PROFILER
+#if LL_PROFILER_ENABLE_TRACY_OPENGL
+#define LL_PROFILE_GPU_ZONE(name) TracyGpuZone(name)
+#define LL_PROFILE_GPU_ZONEC(name,color) TracyGpuZoneC(name,color)
+#define LL_PROFILER_GPU_COLLECT TracyGpuCollect
+#define LL_PROFILER_GPU_CONTEXT TracyGpuContext
+
+// disable memory tracking (incompatible with GPU tracing
+#define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size);
+#define LL_PROFILE_FREE(ptr) (void)(ptr);
+
+#define LL_LABEL_OBJECT_GL(type, name, length, label) glObjectLabel(type, name, length, label)
+#else
+#define LL_PROFILE_GPU_ZONE(name) (void)name;
+#define LL_PROFILE_GPU_ZONEC(name,color) (void)name;(void)color;
+#define LL_PROFILER_GPU_COLLECT
+#define LL_PROFILER_GPU_CONTEXT
+
+#define LL_LABEL_OBJECT_GL(type, name, length, label)
+
+#if LL_PROFILER_CONFIG > 1
+#define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size)
+#define LL_PROFILE_FREE(ptr) TracyFree(ptr)
+#else
+#define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size);
+#define LL_PROFILE_FREE(ptr) (void)(ptr);
+#endif
+
+#endif
+
#include "llprofilercategories.h"
#endif // LL_PROFILER_H
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 155e32ebae..e5060a1076 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -146,7 +146,7 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms)
// schedule a call to threadedUpdate for every call to updateQueue
if (!isQuitting())
{
- mRequestQueue.post([=]()
+ mRequestQueue.postIfOpen([=]()
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update");
mIdleThread = FALSE;
diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp
index 5cbd346411..6852b5536a 100644
--- a/indra/llcommon/llrefcount.cpp
+++ b/indra/llcommon/llrefcount.cpp
@@ -30,7 +30,7 @@
#include "llerror.h"
// maximum reference count before sounding memory leak alarm
-const S32 gMaxRefCount = 65536;
+const S32 gMaxRefCount = S32_MAX;
LLRefCount::LLRefCount(const LLRefCount& other)
: mRef(0)
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 022a5d4659..8b4a0ee6d8 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -37,7 +37,7 @@
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
-# include "zlib/zlib.h" // for davep's dirty little zip functions
+# include "zlib-ng/zlib.h" // for davep's dirty little zip functions
#endif
#if !LL_WINDOWS
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index aeb6ae1b0a..aeb8c530f4 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -36,7 +36,7 @@
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
-# include "zlib/zlib.h"
+# include "zlib-ng/zlib.h"
#endif
#include "llprocessor.h"
@@ -64,6 +64,7 @@ using namespace llsd;
# include <psapi.h> // GetPerformanceInfo() et al.
# include <VersionHelpers.h>
#elif LL_DARWIN
+# include "llsys_objc.h"
# include <errno.h>
# include <sys/sysctl.h>
# include <sys/utsname.h>
@@ -74,12 +75,6 @@ using namespace llsd;
# include <mach/mach_host.h>
# include <mach/task.h>
# include <mach/task_info.h>
-
-// disable warnings about Gestalt calls being deprecated
-// until Apple get's on the ball and provides an alternative
-//
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
#elif LL_LINUX
# include <errno.h>
# include <sys/utsname.h>
@@ -278,12 +273,9 @@ LLOSInfo::LLOSInfo() :
{
const char * DARWIN_PRODUCT_NAME = "Mac OS X";
- SInt32 major_version, minor_version, bugfix_version;
- OSErr r1 = Gestalt(gestaltSystemVersionMajor, &major_version);
- OSErr r2 = Gestalt(gestaltSystemVersionMinor, &minor_version);
- OSErr r3 = Gestalt(gestaltSystemVersionBugFix, &bugfix_version);
+ S32 major_version, minor_version, bugfix_version = 0;
- if((r1 == noErr) && (r2 == noErr) && (r3 == noErr))
+ if (LLGetDarwinOSInfo(major_version, minor_version, bugfix_version))
{
mMajorVer = major_version;
mMinorVer = minor_version;
@@ -456,6 +448,8 @@ LLOSInfo::LLOSInfo() :
dotted_version_string << mMajorVer << "." << mMinorVer << "." << mBuild;
mOSVersionString.append(dotted_version_string.str());
+ mOSBitness = is64Bit() ? 64 : 32;
+ LL_INFOS("LLOSInfo") << "OS bitness: " << mOSBitness << LL_ENDL;
}
#ifndef LL_WINDOWS
@@ -511,6 +505,11 @@ const std::string& LLOSInfo::getOSVersionString() const
return mOSVersionString;
}
+const S32 LLOSInfo::getOSBitness() const
+{
+ return mOSBitness;
+}
+
//static
U32 LLOSInfo::getProcessVirtualSizeKB()
{
@@ -564,6 +563,25 @@ U32 LLOSInfo::getProcessResidentSizeKB()
return resident_size;
}
+//static
+bool LLOSInfo::is64Bit()
+{
+#if LL_WINDOWS
+#if defined(_WIN64)
+ return true;
+#elif defined(_WIN32)
+ // 32-bit viewer may be run on both 32-bit and 64-bit Windows, need to elaborate
+ BOOL f64 = FALSE;
+ return IsWow64Process(GetCurrentProcess(), &f64) && f64;
+#else
+ return false;
+#endif
+#else // ! LL_WINDOWS
+ // we only build a 64-bit mac viewer and currently we don't build for linux at all
+ return true;
+#endif
+}
+
LLCPUInfo::LLCPUInfo()
{
std::ostringstream out;
@@ -571,6 +589,11 @@ LLCPUInfo::LLCPUInfo()
// proc.WriteInfoTextFile("procInfo.txt");
mHasSSE = proc.hasSSE();
mHasSSE2 = proc.hasSSE2();
+ mHasSSE3 = proc.hasSSE3();
+ mHasSSE3S = proc.hasSSE3S();
+ mHasSSE41 = proc.hasSSE41();
+ mHasSSE42 = proc.hasSSE42();
+ mHasSSE4a = proc.hasSSE4a();
mHasAltivec = proc.hasAltivec();
mCPUMHz = (F64)proc.getCPUFrequency();
mFamily = proc.getCPUFamilyName();
@@ -583,6 +606,35 @@ LLCPUInfo::LLCPUInfo()
}
mCPUString = out.str();
LLStringUtil::trim(mCPUString);
+
+ if (mHasSSE)
+ {
+ mSSEVersions.append("1");
+ }
+ if (mHasSSE2)
+ {
+ mSSEVersions.append("2");
+ }
+ if (mHasSSE3)
+ {
+ mSSEVersions.append("3");
+ }
+ if (mHasSSE3S)
+ {
+ mSSEVersions.append("3S");
+ }
+ if (mHasSSE41)
+ {
+ mSSEVersions.append("4.1");
+ }
+ if (mHasSSE42)
+ {
+ mSSEVersions.append("4.2");
+ }
+ if (mHasSSE4a)
+ {
+ mSSEVersions.append("4a");
+ }
}
bool LLCPUInfo::hasAltivec() const
@@ -600,6 +652,31 @@ bool LLCPUInfo::hasSSE2() const
return mHasSSE2;
}
+bool LLCPUInfo::hasSSE3() const
+{
+ return mHasSSE3;
+}
+
+bool LLCPUInfo::hasSSE3S() const
+{
+ return mHasSSE3S;
+}
+
+bool LLCPUInfo::hasSSE41() const
+{
+ return mHasSSE41;
+}
+
+bool LLCPUInfo::hasSSE42() const
+{
+ return mHasSSE42;
+}
+
+bool LLCPUInfo::hasSSE4a() const
+{
+ return mHasSSE4a;
+}
+
F64 LLCPUInfo::getMHz() const
{
return mCPUMHz;
@@ -610,6 +687,11 @@ std::string LLCPUInfo::getCPUString() const
return mCPUString;
}
+const LLSD& LLCPUInfo::getSSEVersions() const
+{
+ return mSSEVersions;
+}
+
void LLCPUInfo::stream(std::ostream& s) const
{
// gather machine information.
@@ -619,6 +701,11 @@ void LLCPUInfo::stream(std::ostream& s) const
// CPU's attributes regardless of platform
s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
+ s << "->mHasSSE3: " << (U32)mHasSSE3 << std::endl;
+ s << "->mHasSSE3S: " << (U32)mHasSSE3S << std::endl;
+ s << "->mHasSSE41: " << (U32)mHasSSE41 << std::endl;
+ s << "->mHasSSE42: " << (U32)mHasSSE42 << std::endl;
+ s << "->mHasSSE4a: " << (U32)mHasSSE4a << std::endl;
s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
s << "->mCPUMHz: " << mCPUMHz << std::endl;
s << "->mCPUString: " << mCPUString << std::endl;
@@ -1323,10 +1410,3 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
if (dst != NULL) gzclose(dst);
return retval;
}
-
-#if LL_DARWIN
-// disable warnings about Gestalt calls being deprecated
-// until Apple get's on the ball and provides an alternative
-//
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index b2f9b6a4ab..0f768938cb 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -51,6 +51,8 @@ public:
const std::string& getOSStringSimple() const;
const std::string& getOSVersionString() const;
+
+ const S32 getOSBitness() const;
S32 mMajorVer;
S32 mMinorVer;
@@ -59,6 +61,7 @@ public:
#ifndef LL_WINDOWS
static S32 getMaxOpenFiles();
#endif
+ static bool is64Bit();
static U32 getProcessVirtualSizeKB();
static U32 getProcessResidentSizeKB();
@@ -66,6 +69,7 @@ private:
std::string mOSString;
std::string mOSStringSimple;
std::string mOSVersionString;
+ S32 mOSBitness;
};
@@ -76,10 +80,16 @@ public:
void stream(std::ostream& s) const;
std::string getCPUString() const;
+ const LLSD& getSSEVersions() const;
bool hasAltivec() const;
bool hasSSE() const;
bool hasSSE2() const;
+ bool hasSSE3() const;
+ bool hasSSE3S() const;
+ bool hasSSE41() const;
+ bool hasSSE42() const;
+ bool hasSSE4a() const;
F64 getMHz() const;
// Family is "AMD Duron" or "Intel Pentium Pro"
@@ -88,10 +98,16 @@ public:
private:
bool mHasSSE;
bool mHasSSE2;
+ bool mHasSSE3;
+ bool mHasSSE3S;
+ bool mHasSSE41;
+ bool mHasSSE42;
+ bool mHasSSE4a;
bool mHasAltivec;
F64 mCPUMHz;
std::string mFamily;
std::string mCPUString;
+ LLSD mSSEVersions;
};
//=============================================================================
diff --git a/indra/llcommon/llsys_objc.h b/indra/llcommon/llsys_objc.h
new file mode 100644
index 0000000000..35599a574b
--- /dev/null
+++ b/indra/llcommon/llsys_objc.h
@@ -0,0 +1,33 @@
+/**
+ * @file llsys_objc.h
+ * @brief Header file for llsys_objc.mm
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSYS_OBJC_H
+#define LL_LLSYS_OBJC_H
+
+bool LLGetDarwinOSInfo(int &major, int &minor, int &patch);
+
+
+#endif // LL_LLSYS_OBJC_H
diff --git a/indra/llcommon/llsys_objc.mm b/indra/llcommon/llsys_objc.mm
new file mode 100644
index 0000000000..cdb1e320d5
--- /dev/null
+++ b/indra/llcommon/llsys_objc.mm
@@ -0,0 +1,64 @@
+/**
+ * @file llsys_objc.mm
+ * @brief obj-c implementation of the system information functions
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llsys_objc.h"
+#import <AppKit/AppKit.h>
+
+static int intAtStringIndex(NSArray *array, int index)
+{
+ return [(NSString *)[array objectAtIndex:index] integerValue];
+}
+
+bool LLGetDarwinOSInfo(int &major, int &minor, int &patch)
+{
+ if (NSAppKitVersionNumber > NSAppKitVersionNumber10_8)
+ {
+ NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
+ major = osVersion.majorVersion;
+ minor = osVersion.minorVersion;
+ patch = osVersion.patchVersion;
+ }
+ else
+ {
+ NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile:
+ @"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"];
+ NSArray* versions = [versionString componentsSeparatedByString:@"."];
+ NSUInteger count = [versions count];
+ if (count > 0)
+ {
+ major = intAtStringIndex(versions, 0);
+ if (count > 1)
+ {
+ minor = intAtStringIndex(versions, 1);
+ if (count > 2)
+ {
+ patch = intAtStringIndex(versions, 2);
+ }
+ }
+ }
+ }
+ return true;
+}
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 39dfee3755..8739eeef00 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -65,6 +65,9 @@ LLTimer* LLTimer::sTimer = NULL;
//---------------------------------------------------------------------------
#if LL_WINDOWS
+
+
+#if 0
void ms_sleep(U32 ms)
{
LL_PROFILE_ZONE_SCOPED;
@@ -83,6 +86,31 @@ U32 micro_sleep(U64 us, U32 max_yields)
ms_sleep((U32)(us / 1000));
return 0;
}
+
+#else
+
+U32 micro_sleep(U64 us, U32 max_yields)
+{
+ LL_PROFILE_ZONE_SCOPED
+ LARGE_INTEGER ft;
+ ft.QuadPart = -static_cast<S64>(us * 10); // '-' using relative time
+
+ HANDLE timer = CreateWaitableTimer(NULL, TRUE, NULL);
+ SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
+ WaitForSingleObject(timer, INFINITE);
+ CloseHandle(timer);
+
+ return 0;
+}
+
+void ms_sleep(U32 ms)
+{
+ LL_PROFILE_ZONE_SCOPED
+ micro_sleep(ms * 1000, 0);
+}
+
+#endif
+
#elif LL_LINUX || LL_DARWIN
static void _sleep_loop(struct timespec& thiswait)
{
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 02ce4823b8..cd4d587752 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -73,6 +73,7 @@ void LLWorkerThread::clearDeleteList()
{
(*iter)->mRequestHandle = LLWorkerThread::nullHandle();
(*iter)->clearFlags(LLWorkerClass::WCF_HAVE_WORK);
+ (*iter)->clearFlags(LLWorkerClass::WCF_WORKING);
delete *iter ;
}
mDeleteList.clear() ;
@@ -97,6 +98,7 @@ S32 LLWorkerThread::update(F32 max_time_ms)
{
if (worker->getFlags(LLWorkerClass::WCF_WORK_FINISHED))
{
+ worker->setFlags(LLWorkerClass::WCF_DELETE_REQUESTED);
delete_list.push_back(worker);
mDeleteList.erase(curiter);
}
diff --git a/indra/llcommon/tests/classic_callback_test.cpp b/indra/llcommon/tests/classic_callback_test.cpp
new file mode 100644
index 0000000000..c060775c24
--- /dev/null
+++ b/indra/llcommon/tests/classic_callback_test.cpp
@@ -0,0 +1,144 @@
+/**
+ * @file classic_callback_test.cpp
+ * @author Nat Goodspeed
+ * @date 2021-09-22
+ * @brief Test ClassicCallback and HeapClassicCallback.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "classic_callback.h"
+// STL headers
+#include <iostream>
+#include <string>
+// std headers
+// external library headers
+// other Linden headers
+#include "../test/lltut.h"
+
+/*****************************************************************************
+* example callback
+*****************************************************************************/
+// callback_t is part of the specification of someAPI()
+typedef void (*callback_t)(const char*, void*);
+void someAPI(callback_t callback, void* userdata)
+{
+ callback("called", userdata);
+}
+
+// C++ callable I want as the actual callback
+struct MyCallback
+{
+ void operator()(const char* msg, void*)
+ {
+ mMsg = msg;
+ }
+
+ void callback_with_extra(const std::string& extra, const char* msg)
+ {
+ mMsg = extra + ' ' + msg;
+ }
+
+ std::string mMsg;
+};
+
+/*****************************************************************************
+* example callback accepting several params, and void* userdata isn't first
+*****************************************************************************/
+typedef std::string (*complex_callback)(int, const char*, void*, double);
+std::string otherAPI(complex_callback callback, void* userdata)
+{
+ return callback(17, "hello world", userdata, 3.0);
+}
+
+// struct into which we can capture complex_callback params
+static struct Data
+{
+ void set(int i, const char* s, double f)
+ {
+ mi = i;
+ ms = s;
+ mf = f;
+ }
+
+ void clear() { set(0, "", 0.0); }
+
+ int mi;
+ std::string ms;
+ double mf;
+} sData;
+
+// C++ callable I want to pass
+struct OtherCallback
+{
+ std::string operator()(int num, const char* str, void*, double approx)
+ {
+ sData.set(num, str, approx);
+ return "hello back!";
+ }
+};
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct classic_callback_data
+ {
+ };
+ typedef test_group<classic_callback_data> classic_callback_group;
+ typedef classic_callback_group::object object;
+ classic_callback_group classic_callbackgrp("classic_callback");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("ClassicCallback");
+ // engage someAPI(MyCallback())
+ auto ccb{ makeClassicCallback<callback_t>(MyCallback()) };
+ someAPI(ccb.get_callback(), ccb.get_userdata());
+ // Unfortunately, with the side effect confined to the bound
+ // MyCallback instance, that call was invisible. Bind a reference to a
+ // named instance by specifying a ref type.
+ MyCallback mcb;
+ ClassicCallback<callback_t, void*, MyCallback&> ccb2(mcb);
+ someAPI(ccb2.get_callback(), ccb2.get_userdata());
+ ensure_equals("failed to call through ClassicCallback", mcb.mMsg, "called");
+
+ // try with HeapClassicCallback
+ mcb.mMsg.clear();
+ auto hcbp{ makeHeapClassicCallback<callback_t>(mcb) };
+ someAPI(hcbp->get_callback(), hcbp->get_userdata());
+ ensure_equals("failed to call through HeapClassicCallback", mcb.mMsg, "called");
+
+ // lambda
+ // The tricky thing here is that a lambda is an unspecified type, so
+ // you can't declare a ClassicCallback<signature, void*, that type>.
+ mcb.mMsg.clear();
+ auto xcb(
+ makeClassicCallback<callback_t>(
+ [&mcb](const char* msg, void*)
+ { mcb.callback_with_extra("extra", msg); }));
+ someAPI(xcb.get_callback(), xcb.get_userdata());
+ ensure_equals("failed to call lambda", mcb.mMsg, "extra called");
+
+ // engage otherAPI(OtherCallback())
+ OtherCallback ocb;
+ // Instead of specifying a reference type for the bound CALLBACK, as
+ // with ccb2 above, you can alternatively move the callable object
+ // into the ClassicCallback (of course AFTER any other reference).
+ // That's why OtherCallback uses external data for its observable side
+ // effect.
+ auto occb{ makeClassicCallback<complex_callback>(std::move(ocb)) };
+ std::string result{ otherAPI(occb.get_callback(), occb.get_userdata()) };
+ ensure_equals("failed to return callback result", result, "hello back!");
+ ensure_equals("failed to set int", sData.mi, 17);
+ ensure_equals("failed to set string", sData.ms, "hello world");
+ ensure_equals("failed to set double", sData.mf, 3.0);
+ }
+} // namespace tut
diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h
index 784327f929..28a0b5e040 100644
--- a/indra/llcommon/workqueue.h
+++ b/indra/llcommon/workqueue.h
@@ -409,7 +409,7 @@ namespace LL
[result = std::forward<CALLABLE>(callable)(),
callback = std::move(callback)]
()
- { callback(std::move(result)); };
+ mutable { callback(std::move(result)); };
}
};
@@ -455,7 +455,7 @@ namespace LL
callable = std::move(callable),
callback = std::move(callback)]
()
- {
+ mutable {
// Use postMaybe() below in case this originating WorkQueue
// has been closed or destroyed. Remember, the outer lambda is
// now running on a thread servicing the target WorkQueue, and
@@ -519,7 +519,7 @@ namespace LL
// We dare to bind a reference to Promise because it's
// specifically designed for cross-thread communication.
[&promise, callable = std::move(callable)]()
- {
+ mutable {
try
{
// call the caller's callable and trigger promise with result
@@ -548,7 +548,7 @@ namespace LL
time,
// &promise is designed for cross-thread access
[&promise, callable = std::move(callable)]()
- {
+ mutable {
try
{
callable();
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 6a301ad50d..c591680250 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -7,7 +7,7 @@ include(GoogleMock)
include(CURL)
include(OpenSSL)
include(NGHTTP2)
-include(ZLIB)
+include(ZLIBNG)
include(LLCoreHttp)
include(LLAddBuildTest)
include(LLMessage)
diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index ee43a599f7..dd3852fb93 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -131,28 +131,44 @@ void LLDiskCache::purge()
LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL;
+ std::vector<bool> file_removed;
+ if (mEnableCacheDebugInfo)
+ {
+ file_removed.reserve(file_info.size());
+ }
uintmax_t file_size_total = 0;
for (file_info_t& entry : file_info)
{
file_size_total += entry.second.first;
- std::string action = "";
- if (file_size_total > mMaxSizeBytes)
+ bool should_remove = file_size_total > mMaxSizeBytes;
+ if (mEnableCacheDebugInfo)
+ {
+ file_removed.push_back(should_remove);
+ }
+ if (should_remove)
{
- action = "DELETE:";
boost::filesystem::remove(entry.second.second, ec);
if (ec.failed())
{
LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL;
}
}
- else
- {
- action = " KEEP:";
- }
+ }
- if (mEnableCacheDebugInfo)
+ if (mEnableCacheDebugInfo)
+ {
+ auto end_time = std::chrono::high_resolution_clock::now();
+ auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
+
+ // Log afterward so it doesn't affect the time measurement
+ // Logging thousands of file results can take hundreds of milliseconds
+ for (size_t i = 0; i < file_info.size(); ++i)
{
+ const file_info_t& entry = file_info[i];
+ const bool removed = file_removed[i];
+ const std::string action = removed ? "DELETE:" : "KEEP:";
+
// have to do this because of LL_INFO/LL_END weirdness
std::ostringstream line;
@@ -163,12 +179,7 @@ void LLDiskCache::purge()
line << " (" << file_size_total << "/" << mMaxSizeBytes << ")";
LL_INFOS() << line.str() << LL_ENDL;
}
- }
- if (mEnableCacheDebugInfo)
- {
- auto end_time = std::chrono::high_resolution_clock::now();
- auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
LL_INFOS() << "Total dir size after purge is " << dirFileSize(mCacheDir) << LL_ENDL;
LL_INFOS() << "Cache purge took " << execute_time << " ms to execute for " << file_info.size() << " files" << LL_ENDL;
}
@@ -209,6 +220,7 @@ const std::string LLDiskCache::assetTypeToString(LLAssetType::EType at)
{ LLAssetType::AT_PERSON, "PERSON" },
{ LLAssetType::AT_MESH, "MESH" },
{ LLAssetType::AT_SETTINGS, "SETTINGS" },
+ { LLAssetType::AT_MATERIAL, "MATERIAL" },
{ LLAssetType::AT_UNKNOWN, "UNKNOWN" }
};
@@ -354,6 +366,38 @@ void LLDiskCache::clearCache()
}
}
+void LLDiskCache::removeOldVFSFiles()
+{
+ //VFS files won't be created, so consider removing this code later
+ static const char CACHE_FORMAT[] = "inv.llsd";
+ static const char DB_FORMAT[] = "db2.x";
+
+ boost::system::error_code ec;
+#if LL_WINDOWS
+ std::wstring cache_path(utf8str_to_utf16str(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "")));
+#else
+ std::string cache_path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""));
+#endif
+ if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
+ {
+ for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
+ {
+ if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
+ {
+ if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) ||
+ (entry.path().string().find(DB_FORMAT) != std::string::npos))
+ {
+ boost::filesystem::remove(entry, ec);
+ if (ec.failed())
+ {
+ LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+}
+
uintmax_t LLDiskCache::dirFileSize(const std::string dir)
{
uintmax_t total_file_size = 0;
diff --git a/indra/llfilesystem/lldiskcache.h b/indra/llfilesystem/lldiskcache.h
index 1cbd2c58aa..b60e74f8c9 100644
--- a/indra/llfilesystem/lldiskcache.h
+++ b/indra/llfilesystem/lldiskcache.h
@@ -140,6 +140,8 @@ class LLDiskCache :
*/
const std::string getCacheInfo();
+ void removeOldVFSFiles();
+
private:
/**
* Utility function to gather the total size the files in a given
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index 8883317751..436b8dd1a2 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -9,7 +9,7 @@ include(LLMath)
include(LLFileSystem)
include(LLKDU)
include(LLImageJ2COJ)
-include(ZLIB)
+include(ZLIBNG)
include(LLAddBuildTest)
include(bugsplat)
include(Tut)
@@ -20,7 +20,7 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${PNG_INCLUDE_DIRS}
- ${ZLIB_INCLUDE_DIRS}
+ ${ZLIBNG_INCLUDE_DIRS}
)
set(llimage_SOURCE_FILES
@@ -74,7 +74,7 @@ target_link_libraries(llimage
${LLCOMMON_LIBRARIES}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
- ${ZLIB_LIBRARIES}
+ ${ZLIBNG_LIBRARIES}
)
# Add tests
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 3a3011d99b..186b01d60c 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -814,6 +814,15 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
++sRawImageCount;
}
+LLImageRaw::LLImageRaw(const U8* data, U16 width, U16 height, S8 components)
+ : LLImageBase()
+{
+ if (allocateDataSize(width, height, components))
+ {
+ memcpy(getData(), data, width * height * components);
+ }
+}
+
LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)
: LLImageBase()
{
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 460d5e0f5b..9e50fd502b 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -184,6 +184,7 @@ protected:
public:
LLImageRaw();
LLImageRaw(U16 width, U16 height, S8 components);
+ LLImageRaw(const U8* data, U16 width, U16 height, S8 components);
LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false);
// Construct using createFromFile (used by tools)
//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp
index 675da65af2..d2c3b419ab 100644
--- a/indra/llinventory/llfoldertype.cpp
+++ b/indra/llinventory/llfoldertype.cpp
@@ -122,6 +122,7 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE, FALSE, FALSE));
addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", TRUE, FALSE, TRUE));
+ addEntry(LLFolderType::FT_MATERIAL, new FolderEntry("material", TRUE, FALSE, TRUE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE, FALSE, FALSE));
};
diff --git a/indra/llinventory/llfoldertype.h b/indra/llinventory/llfoldertype.h
index 1f174520da..19f4d61b5b 100644
--- a/indra/llinventory/llfoldertype.h
+++ b/indra/llinventory/llfoldertype.h
@@ -93,9 +93,13 @@ public:
FT_SETTINGS = 56,
+ FT_MATERIAL = 57,
+
FT_COUNT,
FT_NONE = -1
+
+ // When adding, see note at bottom of LLAssetType::Etype
};
static EType lookup(const std::string& type_name);
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 853ed655f5..ceda2f3caf 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -86,6 +86,7 @@ LLInventoryDictionary::LLInventoryDictionary()
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON));
addEntry(LLInventoryType::IT_SETTINGS, new InventoryEntry("settings", "settings", 1, LLAssetType::AT_SETTINGS));
+ addEntry(LLInventoryType::IT_MATERIAL, new InventoryEntry("material", "render material", 1, LLAssetType::AT_MATERIAL));
}
@@ -153,7 +154,8 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
LLInventoryType::IT_NONE, // 53 AT_RESERVED_4
LLInventoryType::IT_NONE, // 54 AT_RESERVED_5
- LLInventoryType::IT_SETTINGS, // 55 AT_SETTINGS
+ LLInventoryType::IT_SETTINGS, // 55 AT_SETTINGS <- why doesnt this match the value in llassettype.h? -brad
+ LLInventoryType::IT_MATERIAL, // 57 AT_MATERIAL
};
// static
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index b6e7fb047f..a5543814d8 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -65,7 +65,8 @@ public:
IT_WIDGET = 23,
IT_PERSON = 24,
IT_SETTINGS = 25,
- IT_COUNT = 26,
+ IT_MATERIAL = 26,
+ IT_COUNT = 27,
IT_UNKNOWN = 255,
IT_NONE = -1
@@ -118,6 +119,8 @@ public:
ICONNAME_SETTINGS_WATER,
ICONNAME_SETTINGS_DAY,
+ ICONNAME_MATERIAL,
+
ICONNAME_INVALID,
ICONNAME_UNKNOWN,
ICONNAME_COUNT,
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index e2469f3c7e..134e783053 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -234,6 +234,8 @@ void LLParcel::init(const LLUUID &owner_id,
setRegionAllowEnvironmentOverride(FALSE);
setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION);
+
+ setObscureMOAP(false);
}
void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned)
@@ -463,13 +465,13 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr
}
else if ("time" == keyword)
{
- S32 when;
+ S32 when{};
LLStringUtil::convertToS32(value, when);
entry->mTime = when;
}
else if ("flags" == keyword)
{
- U32 setting;
+ U32 setting{};
LLStringUtil::convertToU32(value, setting);
entry->mFlags = setting;
}
@@ -540,6 +542,7 @@ void LLParcel::packMessage(LLSD& msg)
msg["see_avs"] = (LLSD::Boolean) getSeeAVs();
msg["group_av_sounds"] = (LLSD::Boolean) getAllowGroupAVSounds();
msg["any_av_sounds"] = (LLSD::Boolean) getAllowAnyAVSounds();
+ msg["obscure_moap"] = (LLSD::Boolean) getObscureMOAP();
}
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 5d08c1f4c6..f5ee1241ab 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -306,6 +306,7 @@ public:
void setRestrictPushObject(BOOL b) { setParcelFlag(PF_RESTRICT_PUSHOBJECT, b); }
void setAllowGroupAVSounds(BOOL b) { mAllowGroupAVSounds = b; }
void setAllowAnyAVSounds(BOOL b) { mAllowAnyAVSounds = b; }
+ void setObscureMOAP(bool b) { mObscureMOAP = b; }
void setDrawDistance(F32 dist) { mDrawDistance = dist; }
void setSalePrice(S32 price) { mSalePrice = price; }
@@ -517,6 +518,8 @@ public:
BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; }
BOOL getAllowAnyAVSounds() const { return mAllowAnyAVSounds; }
+
+ bool getObscureMOAP() const { return mObscureMOAP; }
F32 getDrawDistance() const { return mDrawDistance; }
S32 getSalePrice() const { return mSalePrice; }
@@ -670,6 +673,7 @@ protected:
BOOL mRegionAllowEnvironmentOverride;
BOOL mAllowGroupAVSounds;
BOOL mAllowAnyAVSounds;
+ bool mObscureMOAP;
S32 mCurrentEnvironmentVersion;
bool mIsDefaultDayCycle;
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 83a92f08d0..d4e616abc2 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -131,6 +131,8 @@ const std::string LLSettingsSky::SETTING_SKY_MOISTURE_LEVEL("moisture_level");
const std::string LLSettingsSky::SETTING_SKY_DROPLET_RADIUS("droplet_radius");
const std::string LLSettingsSky::SETTING_SKY_ICE_LEVEL("ice_level");
+const std::string LLSettingsSky::SETTING_REFLECTION_PROBE_AMBIANCE("reflection_probe_ambiance");
+
const LLUUID LLSettingsSky::DEFAULT_ASSET_ID("3ae23978-ac82-bcf3-a9cb-ba6e52dcb9ad");
static const LLUUID DEFAULT_SUN_ID("32bfbcea-24b1-fb9d-1ef9-48a28a63730f"); // dataserver
@@ -630,6 +632,9 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_REFLECTION_PROBE_AMBIANCE, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+
validation.push_back(Validator(SETTING_RAYLEIGH_CONFIG, true, LLSD::TypeArray, &validateRayleighLayers));
validation.push_back(Validator(SETTING_ABSORPTION_CONFIG, true, LLSD::TypeArray, &validateAbsorptionLayers));
validation.push_back(Validator(SETTING_MIE_CONFIG, true, LLSD::TypeArray, &validateMieLayers));
@@ -755,6 +760,8 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
dfltsetting[SETTING_SKY_DROPLET_RADIUS] = 800.0f;
dfltsetting[SETTING_SKY_ICE_LEVEL] = 0.0f;
+ dfltsetting[SETTING_REFLECTION_PROBE_AMBIANCE] = 0.0f;
+
dfltsetting[SETTING_RAYLEIGH_CONFIG] = rayleighConfigDefault();
dfltsetting[SETTING_MIE_CONFIG] = mieConfigDefault();
dfltsetting[SETTING_ABSORPTION_CONFIG] = absorptionConfigDefault();
@@ -1132,6 +1139,11 @@ void LLSettingsSky::setSkyIceLevel(F32 ice_level)
setValue(SETTING_SKY_ICE_LEVEL, ice_level);
}
+void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance)
+{
+ setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance);
+}
+
void LLSettingsSky::setAmbientColor(const LLColor3 &val)
{
mSettings[SETTING_LEGACY_HAZE][SETTING_AMBIENT] = val.getValue();
@@ -1420,6 +1432,11 @@ F32 LLSettingsSky::getSkyIceLevel() const
return mSettings[SETTING_SKY_ICE_LEVEL].asReal();
}
+F32 LLSettingsSky::getReflectionProbeAmbiance() const
+{
+ return mSettings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal();
+}
+
F32 LLSettingsSky::getSkyBottomRadius() const
{
return mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal();
diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h
index fa9326f006..715d31518b 100644
--- a/indra/llinventory/llsettingssky.h
+++ b/indra/llinventory/llsettingssky.h
@@ -97,6 +97,8 @@ public:
static const std::string SETTING_SKY_DROPLET_RADIUS;
static const std::string SETTING_SKY_ICE_LEVEL;
+ static const std::string SETTING_REFLECTION_PROBE_AMBIANCE;
+
static const std::string SETTING_LEGACY_HAZE;
static const LLUUID DEFAULT_ASSET_ID;
@@ -131,6 +133,8 @@ public:
F32 getSkyDropletRadius() const;
F32 getSkyIceLevel() const;
+ F32 getReflectionProbeAmbiance() const;
+
// Return first (only) profile layer represented in LLSD
LLSD getRayleighConfig() const;
LLSD getMieConfig() const;
@@ -159,6 +163,8 @@ public:
void setSkyDropletRadius(F32 radius);
void setSkyIceLevel(F32 ice_level);
+ void setReflectionProbeAmbiance(F32 ambiance);
+
//---------------------------------------------------------------------
LLColor3 getAmbientColor() const;
void setAmbientColor(const LLColor3 &val);
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 552e820127..4617309606 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -4,12 +4,14 @@ project(llmath)
include(00-Common)
include(LLCommon)
+include(LLMeshOptimizer)
include(bugsplat)
include(Boost)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLMESHOPTIMIZER_INCLUDE_DIRS}
)
set(llmath_SOURCE_FILES
@@ -109,6 +111,7 @@ add_library (llmath ${llmath_SOURCE_FILES})
target_link_libraries(llmath
${LLCOMMON_LIBRARIES}
+ ${LLMESHOPTIMIZER_LIBRARIES}
)
# Add tests
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index a9a54a8113..318ee65cc0 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -48,52 +48,59 @@ extern float gOctreeMinSize;
#define LL_OCTREE_MAX_CAPACITY 128
#endif*/
-template <class T> class LLOctreeNode;
-
-template <class T>
+// T is the type of the element referenced by the octree node.
+// T_PTR determines how pointers to elements are stored internally.
+// LLOctreeNode<T, LLPointer<T>> assumes ownership of inserted elements and
+// deletes elements removed from the tree.
+// LLOctreeNode<T, T*> doesn't take ownership of inserted elements, so the API
+// user is responsible for managing the storage lifecycle of elements added to
+// the tree.
+template <class T, typename T_PTR> class LLOctreeNode;
+
+template <class T, typename T_PTR>
class LLOctreeListener: public LLTreeListener<T>
{
public:
typedef LLTreeListener<T> BaseType;
- typedef LLOctreeNode<T> oct_node;
+ typedef LLOctreeNode<T, T_PTR> oct_node;
virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0;
virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0;
};
-template <class T>
+template <class T, typename T_PTR>
class LLOctreeTraveler
{
public:
- virtual void traverse(const LLOctreeNode<T>* node);
- virtual void visit(const LLOctreeNode<T>* branch) = 0;
+ virtual void traverse(const LLOctreeNode<T, T_PTR>* node);
+ virtual void visit(const LLOctreeNode<T, T_PTR>* branch) = 0;
};
-template <class T>
-class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T>
+template <class T, typename T_PTR>
+class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T, T_PTR>
{
public:
- virtual void traverse(const LLOctreeNode<T>* node) override;
+ virtual void traverse(const LLOctreeNode<T, T_PTR>* node) override;
};
-template <class T>
+template <class T, typename T_PTR>
class alignas(16) LLOctreeNode : public LLTreeNode<T>
{
LL_ALIGN_NEW
public:
- typedef LLOctreeTraveler<T> oct_traveler;
- typedef LLTreeTraveler<T> tree_traveler;
- typedef std::vector< LLPointer<T> > element_list; // note: don't remove the whitespace between "> >"
- typedef LLPointer<T>* element_iter;
- typedef const LLPointer<T>* const_element_iter;
+ typedef LLOctreeTraveler<T, T_PTR> oct_traveler;
+ typedef LLTreeTraveler<T> tree_traveler;
+ typedef std::vector<T_PTR> element_list;
+ typedef typename element_list::iterator element_iter;
+ typedef typename element_list::const_iterator const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
- typedef LLOctreeNode<T>** child_list;
- typedef LLOctreeNode<T>** child_iter;
+ typedef LLOctreeNode<T, T_PTR>** child_list;
+ typedef LLOctreeNode<T, T_PTR>** child_iter;
- typedef LLTreeNode<T> BaseType;
- typedef LLOctreeNode<T> oct_node;
- typedef LLOctreeListener<T> oct_listener;
+ typedef LLTreeNode<T> BaseType;
+ typedef LLOctreeNode<T, T_PTR> oct_node;
+ typedef LLOctreeListener<T, T_PTR> oct_listener;
enum
{
@@ -108,9 +115,6 @@ public:
mOctant(octant)
{
llassert(size[0] >= gOctreeMinSize*0.5f);
- //always keep a NULL terminated list to avoid out of bounds exceptions in debug builds
- mData.push_back(NULL);
- mDataEnd = &mData[0];
mCenter = center;
mSize = size;
@@ -121,8 +125,6 @@ public:
mOctant = ((oct_node*) mParent)->getOctant(mCenter);
}
- mElementCount = 0;
-
clearChildren();
}
@@ -130,15 +132,14 @@ public:
{
BaseType::destroyListeners();
- for (U32 i = 0; i < mElementCount; ++i)
+ const U32 element_count = getElementCount();
+ for (U32 i = 0; i < element_count; ++i)
{
mData[i]->setBinIndex(-1);
mData[i] = NULL;
}
mData.clear();
- mData.push_back(NULL);
- mDataEnd = &mData[0];
for (U32 i = 0; i < getChildCount(); i++)
{
@@ -238,14 +239,12 @@ public:
void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChildCount == 0; }
- U32 getElementCount() const { return mElementCount; }
- bool isEmpty() const { return mElementCount == 0; }
- element_list& getData() { return mData; }
- const element_list& getData() const { return mData; }
- element_iter getDataBegin() { return &mData[0]; }
- element_iter getDataEnd() { return mDataEnd; }
- const_element_iter getDataBegin() const { return &mData[0]; }
- const_element_iter getDataEnd() const { return mDataEnd; }
+ U32 getElementCount() const { return (U32)mData.size(); }
+ bool isEmpty() const { return mData.empty(); }
+ element_iter getDataBegin() { return mData.begin(); }
+ element_iter getDataEnd() { return mData.end(); }
+ const_element_iter getDataBegin() const { return mData.cbegin(); }
+ const_element_iter getDataEnd() const { return mData.cend(); }
U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; }
@@ -263,7 +262,7 @@ public:
U8 idx = mChildMap[i];
if (idx != NO_CHILD_NODES)
{
- LLOctreeNode<T>* child = mChild[idx];
+ oct_node* child = mChild[idx];
if (child->getOctant() != i)
{
@@ -281,7 +280,7 @@ public:
oct_node* getNodeAt(const LLVector4a& pos, const F32& rad)
{
- LLOctreeNode<T>* node = this;
+ oct_node* node = this;
if (node->isInside(pos, rad))
{
@@ -303,7 +302,7 @@ public:
}
else if (!node->contains(rad) && node->getParent())
{ //if we got here, data does not exist in this node
- return ((LLOctreeNode<T>*) node->getParent())->getNodeAt(pos, rad);
+ return ((oct_node*) node->getParent())->getNodeAt(pos, rad);
}
return node;
@@ -318,7 +317,7 @@ public:
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL;
return false;
}
- LLOctreeNode<T>* parent = getOctParent();
+ oct_node* parent = getOctParent();
//is it here?
if (isInside(data->getPositionGroup()))
@@ -326,11 +325,8 @@ public:
if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
- mData.push_back(NULL);
- mData[mElementCount] = data;
- mElementCount++;
- mDataEnd = &mData[mElementCount];
- data->setBinIndex(mElementCount-1);
+ mData.push_back(data);
+ data->setBinIndex(getElementCount() - 1);
BaseType::insert(data);
return true;
}
@@ -354,7 +350,7 @@ public:
size.mul(0.5f);
//push center in direction of data
- LLOctreeNode<T>::pushCenter(center, size, data);
+ oct_node::pushCenter(center, size, data);
// handle case where floating point number gets too small
LLVector4a val;
@@ -366,11 +362,8 @@ public:
if( lt == 0x7 )
{
- mData.push_back(NULL);
- mData[mElementCount] = data;
- mElementCount++;
- mDataEnd = &mData[mElementCount];
- data->setBinIndex(mElementCount-1);
+ mData.push_back(data);
+ data->setBinIndex(getElementCount() - 1);
BaseType::insert(data);
return true;
}
@@ -396,7 +389,7 @@ public:
llassert(size[0] >= gOctreeMinSize*0.5f);
//make the new kid
- child = new LLOctreeNode<T>(center, size, this);
+ child = new oct_node(center, size, this);
addChild(child);
child->insert(data);
@@ -429,28 +422,25 @@ public:
}
void _remove(T* data, S32 i)
- { //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
+ { //precondition -- getElementCount() > 0, idx is in range [0, getElementCount())
- mElementCount--;
data->setBinIndex(-1);
- if (mElementCount > 0)
+ const U32 new_element_count = getElementCount() - 1;
+ if (new_element_count > 0)
{
- if (mElementCount != i)
+ if (new_element_count != i)
{
- mData[i] = mData[mElementCount]; //might unref data, do not access data after this point
+ mData[i] = mData[new_element_count]; //might unref data, do not access data after this point
mData[i]->setBinIndex(i);
}
- mData[mElementCount] = NULL;
+ mData[new_element_count] = NULL;
mData.pop_back();
- mDataEnd = &mData[mElementCount];
}
else
{
mData.clear();
- mData.push_back(NULL);
- mDataEnd = &mData[0];
}
this->notifyRemoval(data);
@@ -463,7 +453,7 @@ public:
S32 i = data->getBinIndex();
- if (i >= 0 && i < mElementCount)
+ if (i >= 0 && i < getElementCount())
{
if (mData[i] == data)
{ //found it
@@ -506,7 +496,8 @@ public:
void removeByAddress(T* data)
{
- for (U32 i = 0; i < mElementCount; ++i)
+ const U32 element_count = getElementCount();
+ for (U32 i = 0; i < element_count; ++i)
{
if (mData[i] == data)
{ //we have data
@@ -518,7 +509,7 @@ public:
for (U32 i = 0; i < getChildCount(); i++)
{ //we don't contain data, so pass this guy down
- LLOctreeNode<T>* child = (LLOctreeNode<T>*) getChild(i);
+ oct_node* child = (oct_node*) getChild(i);
child->removeByAddress(data);
}
}
@@ -672,22 +663,20 @@ protected:
oct_node* mParent;
U8 mOctant;
- LLOctreeNode<T>* mChild[8];
+ oct_node* mChild[8];
U8 mChildMap[8];
U32 mChildCount;
element_list mData;
- element_iter mDataEnd;
- U32 mElementCount;
};
//just like a regular node, except it might expand on insert and compress on balance
-template <class T>
-class LLOctreeRoot : public LLOctreeNode<T>
+template <class T, typename T_PTR>
+class LLOctreeRoot : public LLOctreeNode<T, T_PTR>
{
public:
- typedef LLOctreeNode<T> BaseType;
- typedef LLOctreeNode<T> oct_node;
+ typedef LLOctreeNode<T, T_PTR> BaseType;
+ typedef LLOctreeNode<T, T_PTR> oct_node;
LLOctreeRoot(const LLVector4a& center,
const LLVector4a& size,
@@ -768,7 +757,7 @@ public:
oct_node* node = this->getNodeAt(data);
if (node == this)
{
- LLOctreeNode<T>::insert(data);
+ oct_node::insert(data);
}
else if (node->isInside(data->getPositionGroup()))
{
@@ -788,13 +777,13 @@ public:
LLVector4a center, size;
center = this->getCenter();
size = this->getSize();
- LLOctreeNode<T>::pushCenter(center, size, data);
+ oct_node::pushCenter(center, size, data);
this->setCenter(center);
size.mul(2.f);
this->setSize(size);
this->updateMinMax();
}
- LLOctreeNode<T>::insert(data);
+ oct_node::insert(data);
}
else
{
@@ -806,7 +795,7 @@ public:
//expand this node
LLVector4a newcenter(center);
- LLOctreeNode<T>::pushCenter(newcenter, size, data);
+ oct_node::pushCenter(newcenter, size, data);
this->setCenter(newcenter);
LLVector4a size2 = size;
size2.mul(2.f);
@@ -816,11 +805,11 @@ public:
llassert(size[0] >= gOctreeMinSize);
//copy our children to a new branch
- LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this);
+ oct_node* newnode = new oct_node(center, size, this);
for (U32 i = 0; i < this->getChildCount(); i++)
{
- LLOctreeNode<T>* child = this->getChild(i);
+ oct_node* child = this->getChild(i);
newnode->addChild(child);
}
@@ -846,8 +835,8 @@ public:
//========================
// LLOctreeTraveler
//========================
-template <class T>
-void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
+template <class T, typename T_PTR>
+void LLOctreeTraveler<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)
{
node->accept(this);
for (U32 i = 0; i < node->getChildCount(); i++)
@@ -856,8 +845,8 @@ void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
}
}
-template <class T>
-void LLOctreeTravelerDepthFirst<T>::traverse(const LLOctreeNode<T>* node)
+template <class T, typename T_PTR>
+void LLOctreeTravelerDepthFirst<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)
{
for (U32 i = 0; i < node->getChildCount(); i++)
{
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 5099920f32..a0f3b1463b 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -32,6 +32,7 @@
#include <stdint.h>
#endif
#include <cmath>
+#include <unordered_map>
#include "llerror.h"
@@ -49,8 +50,14 @@
#include "llsdserialize.h"
#include "llvector4a.h"
#include "llmatrix4a.h"
+#include "llmeshoptimizer.h"
#include "lltimer.h"
+#include "mikktspace/mikktspace.h"
+#include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file
+
+#include "meshoptimizer/meshoptimizer.h"
+
#define DEBUG_SILHOUETTE_BINORMALS 0
#define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette
#define DEBUG_SILHOUETTE_EDGE_MAP 0 // DaveP: Use this to display edge map using the silhouette
@@ -370,7 +377,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons
}
}
-class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle>
+class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>
{
public:
const LLVolumeFace* mFace;
@@ -380,7 +387,7 @@ public:
mFace = face;
}
- virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+ virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{ //this is a depth first traversal, so it's safe to assum all children have complete
//bounding data
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
@@ -398,8 +405,7 @@ public:
min = *(tri->mV[0]);
max = *(tri->mV[0]);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
- branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
+ for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
{ //for each triangle in node
//stretch by triangles in node
@@ -683,7 +689,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
- static LLAlignedArray<LLVector4a,64> pt;
+ static thread_local LLAlignedArray<LLVector4a,64> pt;
pt.resize(mTotal) ;
for (S32 i=mTotalOut;i<mTotal;i++)
@@ -1624,9 +1630,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
//genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
genNGon(params, llfloor(MIN_DETAIL_FACES * detail));
- F32 t = 0.f;
- F32 tStep = 1.0f / mPath.size();
-
F32 toggle = 0.5f;
for (S32 i=0;i<(S32)mPath.size();i++)
{
@@ -1635,7 +1638,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
toggle = -0.5f;
else
toggle = 0.5f;
- t += tStep;
}
}
@@ -2097,7 +2099,9 @@ void LLVolume::regen()
void LLVolume::genTangents(S32 face)
{
- mVolumeFaces[face].createTangents();
+ // generate legacy tangents for the specified face
+ llassert(!isMeshAssetLoaded() || mVolumeFaces[face].mTangents != nullptr); // if this is a complete mesh asset, we should already have tangents
+ mVolumeFaces[face].createTangents();
}
LLVolume::~LLVolume()
@@ -2419,13 +2423,19 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
LLSD::Binary pos = mdl[i]["Position"];
LLSD::Binary norm = mdl[i]["Normal"];
+ LLSD::Binary tangent = mdl[i]["Tangent"];
LLSD::Binary tc = mdl[i]["TexCoord0"];
LLSD::Binary idx = mdl[i]["TriangleList"];
-
-
//copy out indices
S32 num_indices = idx.size() / 2;
+ const S32 indices_to_discard = num_indices % 3;
+ if (indices_to_discard > 0)
+ {
+ // Invalid number of triangle indices
+ LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL;
+ num_indices -= indices_to_discard;
+ }
face.resizeIndices(num_indices);
if (num_indices > 2 && !face.mIndices)
@@ -2441,8 +2451,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
U16* indices = (U16*) &(idx[0]);
- U32 count = idx.size()/2;
- for (U32 j = 0; j < count; ++j)
+ for (U32 j = 0; j < num_indices; ++j)
{
face.mIndices[j] = indices[j];
}
@@ -2472,6 +2481,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]);
max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]);
+ //unpack normalized scale/translation
+ if (mdl[i].has("NormalizedScale"))
+ {
+ face.mNormalizedScale.setValue(mdl[i]["NormalizedScale"]);
+ }
+ else
+ {
+ face.mNormalizedScale.set(1, 1, 1);
+ }
+
LLVector4a pos_range;
pos_range.setSub(max_pos, min_pos);
LLVector2 tc_range2 = max_tc - min_tc;
@@ -2522,6 +2541,34 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
}
+#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents
+ {
+ if (!tangent.empty())
+ {
+ face.allocateTangents(face.mNumVertices);
+ U16* t = (U16*)&(tangent[0]);
+
+ // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to
+ // maintain compliance with the GLTF spec
+ LLVector4a* t_out = face.mTangents;
+
+ for (U32 j = 0; j < num_verts; ++j)
+ {
+ t_out->set((F32)t[0], (F32)t[1], (F32)t[2], (F32) t[3]);
+ t_out->div(65535.f);
+ t_out->mul(2.f);
+ t_out->sub(1.f);
+
+ F32* tp = t_out->getF32ptr();
+ tp[3] = tp[3] < 0.f ? -1.f : 1.f;
+
+ t_out++;
+ t += 4;
+ }
+ }
+ }
+#endif
+
{
if (!tc.empty())
{
@@ -2725,7 +2772,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
}
- if (!cacheOptimize())
+ if (!cacheOptimize(true))
{
// Out of memory?
LL_WARNS() << "Failed to optimize!" << LL_ENDL;
@@ -2766,11 +2813,11 @@ void LLVolume::copyVolumeFaces(const LLVolume* volume)
mSculptLevel = 0;
}
-bool LLVolume::cacheOptimize()
+bool LLVolume::cacheOptimize(bool gen_tangents)
{
for (S32 i = 0; i < mVolumeFaces.size(); ++i)
{
- if (!mVolumeFaces[i].cacheOptimize())
+ if (!mVolumeFaces[i].cacheOptimize(gen_tangents))
{
return false;
}
@@ -3834,8 +3881,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
#if DEBUG_SILHOUETTE_EDGE_MAP
//for each triangle
- U32 count = face.mNumIndices;
- for (U32 j = 0; j < count/3; j++) {
+ U32 tri_count = face.mNumIndices / 3;
+ for (U32 j = 0; j < tri_count; j++) {
//get vertices
S32 v1 = face.mIndices[j*3+0];
S32 v2 = face.mIndices[j*3+1];
@@ -3853,7 +3900,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
continue;
}
- if (nIndex >= (S32) count/3) {
+ if (nIndex >= (S32)tri_count) {
continue;
}
//get neighbor vertices
@@ -4053,7 +4100,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
{
if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them
{
- genTangents(i);
+ genTangents(i);
}
if (isUnique())
@@ -4145,13 +4192,13 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
}
else
{
- if (!face.mOctree)
+ if (!face.getOctree())
{
face.createOctree();
}
LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
- intersect.traverse(face.mOctree);
+ intersect.traverse(face.getOctree());
if (intersect.mHitFace)
{
hit_face = i;
@@ -4706,6 +4753,7 @@ LLVolumeFace::LLVolumeFace() :
#endif
mWeightsScrubbed(FALSE),
mOctree(NULL),
+ mOctreeTriangles(NULL),
mOptimized(FALSE)
{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
@@ -4735,8 +4783,9 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mJointIndices(NULL),
#endif
mWeightsScrubbed(FALSE),
- mOctree(NULL)
-{
+ mOctree(NULL),
+ mOctreeTriangles(NULL)
+{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
mCenter = mExtents+2;
*this = src;
@@ -4796,6 +4845,17 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
mTangents = NULL;
}
+ if (src.mTangents)
+ {
+ allocateTangents(src.mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*)mTangents, (F32*)src.mTangents, vert_size);
+ }
+ else
+ {
+ ll_aligned_free_16(mTangents);
+ mTangents = nullptr;
+ }
+
if (src.mWeights)
{
llassert(!mWeights); // don't orphan an old alloc here accidentally
@@ -4839,6 +4899,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
}
mOptimized = src.mOptimized;
+ mNormalizedScale = src.mNormalizedScale;
//delete
return *this;
@@ -4876,8 +4937,7 @@ void LLVolumeFace::freeData()
mJustWeights = NULL;
#endif
- delete mOctree;
- mOctree = NULL;
+ destroyOctree();
}
BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
@@ -4885,8 +4945,7 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
//tree for this face is no longer valid
- delete mOctree;
- mOctree = NULL;
+ destroyOctree();
LL_CHECK_MEMORY
BOOL ret = FALSE ;
@@ -4952,6 +5011,50 @@ bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a
return a.mV[2] < b.mV[2];
}
+void LLVolumeFace::remap()
+{
+ // Generate a remap buffer
+ std::vector<unsigned int> remap(mNumVertices);
+ S32 remap_vertices_count = LLMeshOptimizer::generateRemapMultiU16(&remap[0],
+ mIndices,
+ mNumIndices,
+ mPositions,
+ mNormals,
+ mTexCoords,
+ mNumVertices);
+
+ // Allocate new buffers
+ S32 size = ((mNumIndices * sizeof(U16)) + 0xF) & ~0xF;
+ U16* remap_indices = (U16*)ll_aligned_malloc_16(size);
+
+ S32 tc_bytes_size = ((remap_vertices_count * sizeof(LLVector2)) + 0xF) & ~0xF;
+ LLVector4a* remap_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * remap_vertices_count + tc_bytes_size);
+ LLVector4a* remap_normals = remap_positions + remap_vertices_count;
+ LLVector2* remap_tex_coords = (LLVector2*)(remap_normals + remap_vertices_count);
+
+ // Fill the buffers
+ LLMeshOptimizer::remapIndexBufferU16(remap_indices, mIndices, mNumIndices, &remap[0]);
+ LLMeshOptimizer::remapPositionsBuffer(remap_positions, mPositions, mNumVertices, &remap[0]);
+ LLMeshOptimizer::remapNormalsBuffer(remap_normals, mNormals, mNumVertices, &remap[0]);
+ LLMeshOptimizer::remapUVBuffer(remap_tex_coords, mTexCoords, mNumVertices, &remap[0]);
+
+ // Free unused buffers
+ ll_aligned_free_16(mIndices);
+ ll_aligned_free<64>(mPositions);
+
+ // Tangets are now invalid
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
+
+ // Assign new values
+ mIndices = remap_indices;
+ mPositions = remap_positions;
+ mNormals = remap_normals;
+ mTexCoords = remap_tex_coords;
+ mNumVertices = remap_vertices_count;
+ mNumAllocatedVertices = remap_vertices_count;
+}
+
void LLVolumeFace::optimize(F32 angle_cutoff)
{
LLVolumeFace new_face;
@@ -5308,245 +5411,200 @@ public:
}
};
+// data structures for tangent generation
-bool LLVolumeFace::cacheOptimize()
-{ //optimize for vertex cache according to Forsyth method:
- // http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
-
- llassert(!mOptimized);
- mOptimized = TRUE;
+struct MikktData
+{
+ LLVolumeFace* face;
+ std::vector<LLVector3> p;
+ std::vector<LLVector3> n;
+ std::vector<LLVector2> tc;
+ std::vector<LLVector4> w;
+ std::vector<LLVector4> t;
- LLVCacheLRU cache;
-
- if (mNumVertices < 3 || mNumIndices < 3)
- { //nothing to do
- return true;
- }
+ MikktData(LLVolumeFace* f)
+ : face(f)
+ {
+ U32 count = face->mNumIndices;
- //mapping of vertices to triangles and indices
- std::vector<LLVCacheVertexData> vertex_data;
+ p.resize(count);
+ n.resize(count);
+ tc.resize(count);
+ t.resize(count);
- //mapping of triangles do vertices
- std::vector<LLVCacheTriangleData> triangle_data;
+ if (face->mWeights)
+ {
+ w.resize(count);
+ }
- try
- {
- triangle_data.resize(mNumIndices / 3);
- vertex_data.resize(mNumVertices);
- for (U32 i = 0; i < mNumIndices; i++)
- { //populate vertex data and triangle data arrays
- U16 idx = mIndices[i];
- U32 tri_idx = i / 3;
+ LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]);
+
+
+ for (int i = 0; i < face->mNumIndices; ++i)
+ {
+ U32 idx = face->mIndices[i];
- vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx]));
- vertex_data[idx].mIdx = idx;
- triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]);
+ p[i].set(face->mPositions[idx].getF32ptr());
+ p[i].scaleVec(face->mNormalizedScale); //put mesh in original coordinate frame when reconstructing tangents
+ n[i].set(face->mNormals[idx].getF32ptr());
+ n[i].scaleVec(inv_scale);
+ n[i].normalize();
+ tc[i].set(face->mTexCoords[idx]);
+
+ if (face->mWeights)
+ {
+ w[i].set(face->mWeights[idx].getF32ptr());
+ }
}
}
- catch (std::bad_alloc&)
- {
- // resize or push_back failed
- LL_WARNS("LLVOLUME") << "Resize for " << mNumVertices << " vertices failed" << LL_ENDL;
- return false;
- }
+};
- /*F32 pre_acmr = 1.f;
- //measure cache misses from before rebuild
- {
- LLVCacheFIFO test_cache;
- for (U32 i = 0; i < mNumIndices; ++i)
- {
- test_cache.addVertex(&vertex_data[mIndices[i]]);
- }
- for (U32 i = 0; i < mNumVertices; i++)
- {
- vertex_data[i].mCacheTag = -1;
- }
+bool LLVolumeFace::cacheOptimize(bool gen_tangents)
+{ //optimize for vertex cache according to Forsyth method:
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+ llassert(!mOptimized);
+ mOptimized = TRUE;
- pre_acmr = (F32) test_cache.mMisses/(mNumIndices/3);
- }*/
+ if (gen_tangents && mNormals && mTexCoords)
+ { // generate mikkt space tangents before cache optimizing since the index buffer may change
+ // a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh
+ // and is executed on a background thread
+ SMikkTSpaceInterface ms;
- for (U32 i = 0; i < mNumVertices; i++)
- { //initialize score values (no cache -- might try a fifo cache here)
- LLVCacheVertexData& data = vertex_data[i];
+ ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext)
+ {
+ MikktData* data = (MikktData*)pContext->m_pUserData;
+ LLVolumeFace* face = data->face;
+ return face->mNumIndices / 3;
+ };
- data.mScore = find_vertex_score(data);
- data.mActiveTriangles = data.mTriangles.size();
+ ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace)
+ {
+ return 3;
+ };
- for (U32 j = 0; j < data.mActiveTriangles; ++j)
- {
- data.mTriangles[j]->mScore += data.mScore;
- }
- }
+ ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert)
+ {
+ MikktData* data = (MikktData*)pContext->m_pUserData;
+ F32* v = data->p[iFace * 3 + iVert].mV;
+ fvPosOut[0] = v[0];
+ fvPosOut[1] = v[1];
+ fvPosOut[2] = v[2];
+ };
+
+ ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert)
+ {
+ MikktData* data = (MikktData*)pContext->m_pUserData;
+ F32* n = data->n[iFace * 3 + iVert].mV;
+ fvNormOut[0] = n[0];
+ fvNormOut[1] = n[1];
+ fvNormOut[2] = n[2];
+ };
+
+ ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert)
+ {
+ MikktData* data = (MikktData*)pContext->m_pUserData;
+ F32* tc = data->tc[iFace * 3 + iVert].mV;
+ fvTexcOut[0] = tc[0];
+ fvTexcOut[1] = tc[1];
+ };
- //sort triangle data by score
- std::sort(triangle_data.begin(), triangle_data.end());
+ ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert)
+ {
+ MikktData* data = (MikktData*)pContext->m_pUserData;
+ S32 i = iFace * 3 + iVert;
+
+ data->t[i].set(fvTangent);
+ data->t[i].mV[3] = fSign;
+ };
- std::vector<U16> new_indices;
+ ms.m_setTSpace = nullptr;
- LLVCacheTriangleData* tri;
+ MikktData data(this);
- //prime pump by adding first triangle to cache;
- tri = &(triangle_data[0]);
- cache.addTriangle(tri);
- new_indices.push_back(tri->mVertex[0]->mIdx);
- new_indices.push_back(tri->mVertex[1]->mIdx);
- new_indices.push_back(tri->mVertex[2]->mIdx);
- tri->complete();
+ SMikkTSpaceContext ctx = { &ms, &data };
- U32 breaks = 0;
- for (U32 i = 1; i < mNumIndices/3; ++i)
- {
- cache.updateScores();
- tri = cache.mBestTriangle;
- if (!tri)
- {
- breaks++;
- for (U32 j = 0; j < triangle_data.size(); ++j)
- {
- if (triangle_data[j].mActive)
- {
- tri = &(triangle_data[j]);
- break;
- }
- }
- }
-
- cache.addTriangle(tri);
- new_indices.push_back(tri->mVertex[0]->mIdx);
- new_indices.push_back(tri->mVertex[1]->mIdx);
- new_indices.push_back(tri->mVertex[2]->mIdx);
- tri->complete();
- }
+ genTangSpaceDefault(&ctx);
- for (U32 i = 0; i < mNumIndices; ++i)
- {
- mIndices[i] = new_indices[i];
- }
+ //re-weld
+ meshopt_Stream mos[] =
+ {
+ { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) },
+ { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) },
+ { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) },
+ { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) },
+ { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) }
+ };
- /*F32 post_acmr = 1.f;
- //measure cache misses from after rebuild
- {
- LLVCacheFIFO test_cache;
- for (U32 i = 0; i < mNumVertices; i++)
- {
- vertex_data[i].mCacheTag = -1;
- }
+ std::vector<U32> remap;
+ remap.resize(data.p.size());
- for (U32 i = 0; i < mNumIndices; ++i)
- {
- test_cache.addVertex(&vertex_data[mIndices[i]]);
- }
-
- post_acmr = (F32) test_cache.mMisses/(mNumIndices/3);
- }*/
+ U32 stream_count = data.w.empty() ? 4 : 5;
- //optimize for pre-TnL cache
-
- //allocate space for new buffer
- S32 num_verts = mNumVertices;
- S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF;
- LLVector4a* pos = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+size);
- if (pos == NULL)
- {
- LL_WARNS("LLVOLUME") << "Allocation of positions vector[" << sizeof(LLVector4a) * 2 * num_verts + size << "] failed. " << LL_ENDL;
- return false;
- }
- LLVector4a* norm = pos + num_verts;
- LLVector2* tc = (LLVector2*) (norm + num_verts);
+ U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count);
- LLVector4a* wght = NULL;
- if (mWeights)
- {
- wght = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
- if (wght == NULL)
- {
- ll_aligned_free<64>(pos);
- LL_WARNS("LLVOLUME") << "Allocation of weights[" << sizeof(LLVector4a) * num_verts << "] failed" << LL_ENDL;
- return false;
- }
- }
+ std::vector<U32> indices;
+ indices.resize(mNumIndices);
- LLVector4a* binorm = NULL;
- if (mTangents)
- {
- binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
- if (binorm == NULL)
- {
- ll_aligned_free<64>(pos);
- ll_aligned_free_16(wght);
- LL_WARNS("LLVOLUME") << "Allocation of binormals[" << sizeof(LLVector4a)*num_verts << "] failed" << LL_ENDL;
- return false;
- }
- }
+ //copy results back into volume
+ resizeVertices(vert_count);
- //allocate mapping of old indices to new indices
- std::vector<S32> new_idx;
+ if (!data.w.empty())
+ {
+ allocateWeights(vert_count);
+ }
- try
- {
- new_idx.resize(mNumVertices, -1);
- }
- catch (std::bad_alloc&)
- {
- ll_aligned_free<64>(pos);
- ll_aligned_free_16(wght);
- ll_aligned_free_16(binorm);
- LL_WARNS("LLVOLUME") << "Resize failed: " << mNumVertices << LL_ENDL;
- return false;
- }
+ allocateTangents(mNumVertices);
- S32 cur_idx = 0;
- for (U32 i = 0; i < mNumIndices; ++i)
- {
- U16 idx = mIndices[i];
- if (new_idx[idx] == -1)
- { //this vertex hasn't been added yet
- new_idx[idx] = cur_idx;
+ for (int i = 0; i < mNumIndices; ++i)
+ {
+ U32 src_idx = i;
+ U32 dst_idx = remap[i];
+ mIndices[i] = dst_idx;
- //copy vertex data
- pos[cur_idx] = mPositions[idx];
- norm[cur_idx] = mNormals[idx];
- tc[cur_idx] = mTexCoords[idx];
- if (mWeights)
- {
- wght[cur_idx] = mWeights[idx];
- }
- if (mTangents)
- {
- binorm[cur_idx] = mTangents[idx];
- }
+ mPositions[dst_idx].load3(data.p[src_idx].mV);
+ mNormals[dst_idx].load3(data.n[src_idx].mV);
+ mTexCoords[dst_idx] = data.tc[src_idx];
- cur_idx++;
- }
- }
+ mTangents[dst_idx].loadua(data.t[src_idx].mV);
- for (U32 i = 0; i < mNumIndices; ++i)
- {
- mIndices[i] = new_idx[mIndices[i]];
- }
-
- ll_aligned_free<64>(mPositions);
- // DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
- ll_aligned_free_16(mWeights);
- ll_aligned_free_16(mTangents);
-#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
- ll_aligned_free_16(mJointIndices);
- ll_aligned_free_16(mJustWeights);
- mJustWeights = NULL;
- mJointIndices = NULL; // filled in later as necessary by skinning code for acceleration
-#endif
+ if (mWeights)
+ {
+ mWeights[dst_idx].loadua(data.w[src_idx].mV);
+ }
+ }
- mPositions = pos;
- mNormals = norm;
- mTexCoords = tc;
- mWeights = wght;
- mTangents = binorm;
- //std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
- //LL_INFOS() << result << LL_ENDL;
+ // put back in normalized coordinate frame
+ LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]);
+ LLVector4a scale;
+ scale.load3(mNormalizedScale.mV);
+ scale.getF32ptr()[3] = 1.f;
+
+ for (int i = 0; i < mNumVertices; ++i)
+ {
+ mPositions[i].mul(inv_scale);
+ mNormals[i].mul(scale);
+ mNormals[i].normalize3();
+ F32 w = mTangents[i].getF32ptr()[3];
+ mTangents[i].mul(scale);
+ mTangents[i].normalize3();
+ mTangents[i].getF32ptr()[3] = w;
+ }
+ }
+
+ // cache optimize index buffer
+
+ // meshopt needs scratch space, do some pointer shuffling to avoid an extra index buffer copy
+ U16* src_indices = mIndices;
+ mIndices = nullptr;
+ resizeIndices(mNumIndices);
+
+ meshopt_optimizeVertexCache<U16>(mIndices, src_indices, mNumIndices, mNumVertices);
+
+ ll_aligned_free_16(src_indices);
return true;
}
@@ -5555,21 +5613,27 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
- if (mOctree)
+ if (getOctree())
{
return;
}
- mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL);
+ llassert(mNumIndices % 3 == 0);
+
+ mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, NULL);
new LLVolumeOctreeListener(mOctree);
+ const U32 num_triangles = mNumIndices / 3;
+ // Initialize all the triangles we need
+ mOctreeTriangles = new LLVolumeTriangle[num_triangles];
- for (U32 i = 0; i < mNumIndices; i+= 3)
+ for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index)
{ //for each triangle
- LLPointer<LLVolumeTriangle> tri = new LLVolumeTriangle();
+ const U32 index = triangle_index * 3;
+ LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index];
- const LLVector4a& v0 = mPositions[mIndices[i]];
- const LLVector4a& v1 = mPositions[mIndices[i+1]];
- const LLVector4a& v2 = mPositions[mIndices[i+2]];
+ const LLVector4a& v0 = mPositions[mIndices[index]];
+ const LLVector4a& v1 = mPositions[mIndices[index + 1]];
+ const LLVector4a& v2 = mPositions[mIndices[index + 2]];
//store pointers to vertex data
tri->mV[0] = &v0;
@@ -5577,9 +5641,9 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
tri->mV[2] = &v2;
//store indices
- tri->mIndex[0] = mIndices[i];
- tri->mIndex[1] = mIndices[i+1];
- tri->mIndex[2] = mIndices[i+2];
+ tri->mIndex[0] = mIndices[index];
+ tri->mIndex[1] = mIndices[index + 1];
+ tri->mIndex[2] = mIndices[index + 2];
//get minimum point
LLVector4a min = v0;
@@ -5622,6 +5686,19 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
}
}
+void LLVolumeFace::destroyOctree()
+{
+ delete mOctree;
+ mOctree = NULL;
+ delete[] mOctreeTriangles;
+ mOctreeTriangles = NULL;
+}
+
+const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree() const
+{
+ return mOctree;
+}
+
void LLVolumeFace::swapData(LLVolumeFace& rhs)
{
@@ -6337,35 +6414,31 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
void LLVolumeFace::createTangents()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- if (!mTangents)
- {
- allocateTangents(mNumVertices);
-
- //generate tangents
- //LLVector4a* pos = mPositions;
- //LLVector2* tc = (LLVector2*) mTexCoords;
- LLVector4a* binorm = (LLVector4a*) mTangents;
+ if (!mTangents)
+ {
+ allocateTangents(mNumVertices);
+
+ //generate tangents
+ LLVector4a* ptr = (LLVector4a*)mTangents;
- LLVector4a* end = mTangents+mNumVertices;
- while (binorm < end)
- {
- (*binorm++).clear();
- }
+ LLVector4a* end = mTangents + mNumVertices;
+ while (ptr < end)
+ {
+ (*ptr++).clear();
+ }
- binorm = mTangents;
+ CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents);
- CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
+ //normalize normals
+ for (U32 i = 0; i < mNumVertices; i++)
+ {
+ //bump map/planar projection code requires normals to be normalized
+ mNormals[i].normalize3fast();
+ }
+ }
- //normalize tangents
- for (U32 i = 0; i < mNumVertices; i++)
- {
- //binorm[i].normalize3fast();
- //bump map/planar projection code requires normals to be normalized
- mNormals[i].normalize3fast();
- }
- }
}
void LLVolumeFace::resizeVertices(S32 num_verts)
@@ -6493,6 +6566,7 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts)
void LLVolumeFace::resizeIndices(S32 num_indices)
{
ll_aligned_free_16(mIndices);
+ llassert(num_indices % 3 == 0);
if (num_indices)
{
@@ -6629,13 +6703,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
else
{
// Get s value for tex-coord.
- if (!flat)
+ S32 index = mBeginS + s;
+ if (index >= profile.size())
+ {
+ // edge?
+ ss = flat ? 1.f - begin_stex : 1.f;
+ }
+ else if (!flat)
{
- ss = profile[mBeginS + s][2];
+ ss = profile[index][2];
}
else
{
- ss = profile[mBeginS + s][2] - begin_stex;
+ ss = profile[index][2] - begin_stex;
}
}
@@ -6821,7 +6901,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LLVector4a* norm = mNormals;
- static LLAlignedArray<LLVector4a, 64> triangle_normals;
+ static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals;
try
{
triangle_normals.resize(count);
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index c0b224b1ff..e8faf549f4 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -35,7 +35,8 @@ class LLVolumeParams;
class LLProfile;
class LLPath;
-template <class T> class LLOctreeNode;
+template<class T> class LLPointer;
+template <class T, typename T_PTR> class LLOctreeNode;
class LLVolumeFace;
class LLVolume;
@@ -902,10 +903,17 @@ public:
typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap;
};
+ // Eliminates non unique triangles, takes positions,
+ // normals and texture coordinates into account.
+ void remap();
+
void optimize(F32 angle_cutoff = 2.f);
- bool cacheOptimize();
+ bool cacheOptimize(bool gen_tangents = false);
void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));
+ void destroyOctree();
+ // Get a reference to the octree, which may be null
+ const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* getOctree() const;
enum
{
@@ -952,10 +960,6 @@ public:
// indexes for mPositions/mNormals/mTexCoords
U16* mIndices;
- // vertex buffer filled in by LLFace to cache this volume face geometry in vram
- // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer)
- mutable LLPointer<LLRefCount> mVertexBuffer;
-
std::vector<S32> mEdge;
//list of skin weights for rigged volumes
@@ -973,13 +977,19 @@ public:
// Which joints are rigged to, and the bounding box of any rigged
// vertices per joint.
LLJointRiggingInfoTab mJointRiggingInfoTab;
-
- LLOctreeNode<LLVolumeTriangle>* mOctree;
//whether or not face has been cache optimized
BOOL mOptimized;
+ // if this is a mesh asset, scale and translation that were applied
+ // when encoding the source mesh into a unit cube
+ // used for regenerating tangents
+ LLVector3 mNormalizedScale = LLVector3(1,1,1);
+
private:
+ LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* mOctree;
+ LLVolumeTriangle* mOctreeTriangles;
+
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE);
@@ -1024,7 +1034,7 @@ public:
void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
void regen();
- void genTangents(S32 face);
+ void genTangents(S32 face);
BOOL isConvex() const;
BOOL isCap(S32 face);
@@ -1078,7 +1088,10 @@ public:
void copyVolumeFaces(const LLVolume* volume);
void copyFacesTo(std::vector<LLVolumeFace> &faces) const;
void copyFacesFrom(const std::vector<LLVolumeFace> &faces);
- bool cacheOptimize();
+
+ // use meshoptimizer to optimize index buffer for vertex shader cache
+ // gen_tangents - if true, generate MikkTSpace tangents if needed before optimizing index buffer
+ bool cacheOptimize(bool gen_tangents = false);
private:
void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp
index fb232d5f6c..6894d04d3c 100644
--- a/indra/llmath/llvolumeoctree.cpp
+++ b/indra/llmath/llvolumeoctree.cpp
@@ -75,7 +75,7 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c
}
-LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node)
+LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
node->addListener(this);
}
@@ -85,13 +85,12 @@ LLVolumeOctreeListener::~LLVolumeOctreeListener()
}
-void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
- LLOctreeNode<LLVolumeTriangle>* child)
+void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent,
+ LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child)
{
new LLVolumeOctreeListener(child);
}
-
LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
const LLVolumeFace* face, F32* closest_t,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
@@ -108,7 +107,7 @@ LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& sta
mEnd.setAdd(mStart, mDir);
}
-void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>* node)
+void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
@@ -122,9 +121,9 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
}
}
-void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node)
+void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
+ for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter =
node->getDataBegin(); iter != node->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
@@ -219,7 +218,7 @@ const F32& LLVolumeTriangle::getBinRadius() const
//TEST CODE
-void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{
LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
@@ -256,7 +255,7 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
//children fit, check data
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
iter != branch->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
@@ -273,4 +272,3 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
}
-
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index b2bc440368..d65bca5e52 100644
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -77,11 +77,11 @@ public:
};
-class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
+class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle, LLVolumeTriangle*>
{
LL_ALIGN_NEW
public:
- LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node);
+ LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
~LLVolumeOctreeListener();
LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs)
@@ -96,11 +96,9 @@ public:
}
//LISTENER FUNCTIONS
- virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
- LLOctreeNode<LLVolumeTriangle>* child);
+ virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child);
virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { }
- virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent,
- const LLOctreeNode<LLVolumeTriangle>* child) { }
+ virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child) { }
virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { }
@@ -111,7 +109,7 @@ public:
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
};
-class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle>
+class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
{
public:
const LLVolumeFace* mFace;
@@ -129,14 +127,14 @@ public:
const LLVolumeFace* face, F32* closest_t,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
- void traverse(const LLOctreeNode<LLVolumeTriangle>* node);
+ void traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
- virtual void visit(const LLOctreeNode<LLVolumeTriangle>* node);
+ virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
};
-class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle>
+class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
{
- virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch);
+ virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch);
};
#endif
diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h
index 43a632408c..d925f56e97 100644
--- a/indra/llmath/v3color.h
+++ b/indra/llmath/v3color.h
@@ -33,6 +33,7 @@ class LLVector4;
#include "llerror.h"
#include "llmath.h"
#include "llsd.h"
+#include "v3math.h" // needed for linearColor3v implemtation below
#include <string.h>
// LLColor3 = |r g b|
@@ -87,6 +88,16 @@ public:
const LLColor3& set(F32 x, F32 y, F32 z); // Sets LLColor3 to (x, y, z)
const LLColor3& set(const LLColor3 &vec); // Sets LLColor3 to vec
const LLColor3& set(const F32 *vec); // Sets LLColor3 to vec
+
+ // set from a vector of unknown type and size
+ // may leave some data unmodified
+ template<typename T>
+ const LLColor3& set(const std::vector<T>& v);
+
+ // write to a vector of unknown type and size
+ // maye leave some data unmodified
+ template<typename T>
+ void write(std::vector<T>& v) const;
F32 magVec() const; // deprecated
F32 magVecSquared() const; // deprecated
@@ -484,13 +495,45 @@ inline const LLColor3 srgbColor3(const LLColor3 &a) {
return srgbColor;
}
-inline const LLColor3 linearColor3(const LLColor3 &a) {
+inline const LLColor3 linearColor3p(const F32* v) {
LLColor3 linearColor;
- linearColor.mV[0] = sRGBtoLinear(a.mV[0]);
- linearColor.mV[1] = sRGBtoLinear(a.mV[1]);
- linearColor.mV[2] = sRGBtoLinear(a.mV[2]);
+ linearColor.mV[0] = sRGBtoLinear(v[0]);
+ linearColor.mV[1] = sRGBtoLinear(v[1]);
+ linearColor.mV[2] = sRGBtoLinear(v[2]);
return linearColor;
}
+template<class T>
+inline const LLColor3 linearColor3(const T& a) {
+ return linearColor3p(a.mV);
+}
+
+template<class T>
+inline const LLVector3 linearColor3v(const T& a) {
+ return LLVector3(linearColor3p(a.mV).mV);
+}
+
+template<typename T>
+const LLColor3& LLColor3::set(const std::vector<T>& v)
+{
+ for (S32 i = 0; i < llmin((S32)v.size(), 3); ++i)
+ {
+ mV[i] = v[i];
+ }
+
+ return *this;
+}
+
+// write to a vector of unknown type and size
+// maye leave some data unmodified
+template<typename T>
+void LLColor3::write(std::vector<T>& v) const
+{
+ for (int i = 0; i < llmin((S32)v.size(), 3); ++i)
+ {
+ v[i] = mV[i];
+ }
+}
+
#endif
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index 175edf1471..daa61594fb 100644
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -88,8 +88,18 @@ class LLColor4
const LLColor4& set(const LLColor3 &vec); // Sets LLColor4 to LLColor3 vec (no change in alpha)
const LLColor4& set(const LLColor3 &vec, F32 a); // Sets LLColor4 to LLColor3 vec, with alpha specified
const LLColor4& set(const F32 *vec); // Sets LLColor4 to vec
- const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled.
+ const LLColor4& set(const F64 *vec); // Sets LLColor4 to (double)vec
+ const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled.
+ // set from a vector of unknown type and size
+ // may leave some data unmodified
+ template<typename T>
+ const LLColor4& set(const std::vector<T>& v);
+
+ // write to a vector of unknown type and size
+ // maye leave some data unmodified
+ template<typename T>
+ void write(std::vector<T>& v) const;
const LLColor4& setAlpha(F32 a);
@@ -334,6 +344,15 @@ inline const LLColor4& LLColor4::set(const F32 *vec)
return (*this);
}
+inline const LLColor4& LLColor4::set(const F64 *vec)
+{
+ mV[VX] = static_cast<F32>(vec[VX]);
+ mV[VY] = static_cast<F32>(vec[VY]);
+ mV[VZ] = static_cast<F32>(vec[VZ]);
+ mV[VW] = static_cast<F32>(vec[VW]);
+ return (*this);
+}
+
// deprecated
inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z)
{
@@ -680,5 +699,25 @@ inline const LLColor4 linearColor4(const LLColor4 &a)
return linearColor;
}
+template<typename T>
+const LLColor4& LLColor4::set(const std::vector<T>& v)
+{
+ for (S32 i = 0; i < llmin((S32)v.size(), 4); ++i)
+ {
+ mV[i] = v[i];
+ }
+
+ return *this;
+}
+
+template<typename T>
+void LLColor4::write(std::vector<T>& v) const
+{
+ for (int i = 0; i < llmin((S32)v.size(), 4); ++i)
+ {
+ v[i] = mV[i];
+ }
+}
+
#endif
diff --git a/indra/llmeshoptimizer/llmeshoptimizer.cpp b/indra/llmeshoptimizer/llmeshoptimizer.cpp
index a879389c5a..c178348968 100644
--- a/indra/llmeshoptimizer/llmeshoptimizer.cpp
+++ b/indra/llmeshoptimizer/llmeshoptimizer.cpp
@@ -28,6 +28,9 @@
#include "meshoptimizer.h"
+#include "llmath.h"
+#include "v2math.h"
+
LLMeshOptimizer::LLMeshOptimizer()
{
// Todo: Looks like for memory management, we can add allocator and deallocator callbacks
@@ -40,25 +43,219 @@ LLMeshOptimizer::~LLMeshOptimizer()
}
//static
-void LLMeshOptimizer::generateShadowIndexBuffer(U16 *destination,
- const U16 *indices,
+void LLMeshOptimizer::generateShadowIndexBufferU32(U32 *destination,
+ const U32 *indices,
U64 index_count,
- const LLVector4a *vertex_positions,
- U64 vertex_count,
- U64 vertex_positions_stride
+ const LLVector4a * vertex_positions,
+ const LLVector4a * normals,
+ const LLVector2 * text_coords,
+ U64 vertex_count
)
{
- meshopt_generateShadowIndexBuffer<unsigned short>(destination,
+ meshopt_Stream streams[3];
+
+ S32 index = 0;
+ if (vertex_positions)
+ {
+ streams[index].data = (const float*)vertex_positions;
+ // Despite being LLVector4a, only x, y and z are in use
+ streams[index].size = sizeof(F32) * 3;
+ streams[index].stride = sizeof(F32) * 4;
+ index++;
+ }
+ if (normals)
+ {
+ streams[index].data = (const float*)normals;
+ streams[index].size = sizeof(F32) * 3;
+ streams[index].stride = sizeof(F32) * 4;
+ index++;
+ }
+ if (text_coords)
+ {
+ streams[index].data = (const float*)text_coords;
+ streams[index].size = sizeof(F32) * 2;
+ streams[index].stride = sizeof(F32) * 2;
+ index++;
+ }
+
+ if (index == 0)
+ {
+ // invalid
+ return;
+ }
+
+ meshopt_generateShadowIndexBufferMulti<unsigned int>(destination,
indices,
index_count,
- (const float*)vertex_positions, // verify that it is correct to convert to float
vertex_count,
- sizeof(LLVector4a),
- vertex_positions_stride
+ streams,
+ index
);
}
//static
+void LLMeshOptimizer::generateShadowIndexBufferU16(U16 *destination,
+ const U16 *indices,
+ U64 index_count,
+ const LLVector4a * vertex_positions,
+ const LLVector4a * normals,
+ const LLVector2 * text_coords,
+ U64 vertex_count
+)
+{
+ meshopt_Stream streams[3];
+
+ S32 index = 0;
+ if (vertex_positions)
+ {
+ streams[index].data = (const float*)vertex_positions;
+ streams[index].size = sizeof(F32) * 3;
+ streams[index].stride = sizeof(F32) * 4;
+ index++;
+ }
+ if (normals)
+ {
+ streams[index].data = (const float*)normals;
+ streams[index].size = sizeof(F32) * 3;
+ streams[index].stride = sizeof(F32) * 4;
+ index++;
+ }
+ if (text_coords)
+ {
+ streams[index].data = (const float*)text_coords;
+ streams[index].size = sizeof(F32) * 2;
+ streams[index].stride = sizeof(F32) * 2;
+ index++;
+ }
+
+ if (index == 0)
+ {
+ // invalid
+ return;
+ }
+
+ meshopt_generateShadowIndexBufferMulti<unsigned short>(destination,
+ indices,
+ index_count,
+ vertex_count,
+ streams,
+ index);
+}
+
+void LLMeshOptimizer::optimizeVertexCacheU32(U32 * destination, const U32 * indices, U64 index_count, U64 vertex_count)
+{
+ meshopt_optimizeVertexCache<unsigned int>(destination, indices, index_count, vertex_count);
+}
+
+void LLMeshOptimizer::optimizeVertexCacheU16(U16 * destination, const U16 * indices, U64 index_count, U64 vertex_count)
+{
+ meshopt_optimizeVertexCache<unsigned short>(destination, indices, index_count, vertex_count);
+}
+
+size_t LLMeshOptimizer::generateRemapMultiU32(
+ unsigned int* remap,
+ const U32 * indices,
+ U64 index_count,
+ const LLVector4a * vertex_positions,
+ const LLVector4a * normals,
+ const LLVector2 * text_coords,
+ U64 vertex_count)
+{
+ meshopt_Stream streams[] = {
+ {(const float*)vertex_positions, sizeof(F32) * 3, sizeof(F32) * 4},
+ {(const float*)normals, sizeof(F32) * 3, sizeof(F32) * 4},
+ {(const float*)text_coords, sizeof(F32) * 2, sizeof(F32) * 2},
+ };
+
+ // Remap can function without indices,
+ // but providing indices helps with removing unused vertices
+ U64 indeces_cmp = indices ? index_count : vertex_count;
+
+ // meshopt_generateVertexRemapMulti will throw an assert if (indices[i] >= vertex_count)
+ return meshopt_generateVertexRemapMulti(&remap[0], indices, indeces_cmp, vertex_count, streams, sizeof(streams) / sizeof(streams[0]));
+}
+
+size_t LLMeshOptimizer::generateRemapMultiU16(
+ unsigned int* remap,
+ const U16 * indices,
+ U64 index_count,
+ const LLVector4a * vertex_positions,
+ const LLVector4a * normals,
+ const LLVector2 * text_coords,
+ U64 vertex_count)
+{
+ S32 out_of_range_count = 0;
+ U32* indices_u32 = NULL;
+ if (indices)
+ {
+ indices_u32 = (U32*)ll_aligned_malloc_32(index_count * sizeof(U32));
+ for (U64 i = 0; i < index_count; i++)
+ {
+ if (indices[i] < vertex_count)
+ {
+ indices_u32[i] = (U32)indices[i];
+ }
+ else
+ {
+ out_of_range_count++;
+ indices_u32[i] = 0;
+ }
+ }
+ }
+
+ if (out_of_range_count)
+ {
+ LL_WARNS() << out_of_range_count << " indices are out of range." << LL_ENDL;
+ }
+
+ size_t unique = generateRemapMultiU32(remap, indices_u32, index_count, vertex_positions, normals, text_coords, vertex_count);
+
+ ll_aligned_free_32(indices_u32);
+
+ return unique;
+}
+
+void LLMeshOptimizer::remapIndexBufferU32(U32 * destination_indices,
+ const U32 * indices,
+ U64 index_count,
+ const unsigned int* remap)
+{
+ meshopt_remapIndexBuffer<unsigned int>(destination_indices, indices, index_count, remap);
+}
+
+void LLMeshOptimizer::remapIndexBufferU16(U16 * destination_indices,
+ const U16 * indices,
+ U64 index_count,
+ const unsigned int* remap)
+{
+ meshopt_remapIndexBuffer<unsigned short>(destination_indices, indices, index_count, remap);
+}
+
+void LLMeshOptimizer::remapPositionsBuffer(LLVector4a * destination_vertices,
+ const LLVector4a * vertex_positions,
+ U64 vertex_count,
+ const unsigned int* remap)
+{
+ meshopt_remapVertexBuffer((float*)destination_vertices, (const float*)vertex_positions, vertex_count, sizeof(LLVector4a), remap);
+}
+
+void LLMeshOptimizer::remapNormalsBuffer(LLVector4a * destination_normalss,
+ const LLVector4a * normals,
+ U64 mormals_count,
+ const unsigned int* remap)
+{
+ meshopt_remapVertexBuffer((float*)destination_normalss, (const float*)normals, mormals_count, sizeof(LLVector4a), remap);
+}
+
+void LLMeshOptimizer::remapUVBuffer(LLVector2 * destination_uvs,
+ const LLVector2 * uv_positions,
+ U64 uv_count,
+ const unsigned int* remap)
+{
+ meshopt_remapVertexBuffer((float*)destination_uvs, (const float*)uv_positions, uv_count, sizeof(LLVector2), remap);
+}
+
+//static
U64 LLMeshOptimizer::simplifyU32(U32 *destination,
const U32 *indices,
U64 index_count,
diff --git a/indra/llmeshoptimizer/llmeshoptimizer.h b/indra/llmeshoptimizer/llmeshoptimizer.h
index e8dd16dae9..ea965d6b47 100644
--- a/indra/llmeshoptimizer/llmeshoptimizer.h
+++ b/indra/llmeshoptimizer/llmeshoptimizer.h
@@ -28,7 +28,8 @@
#include "linden_common.h"
-#include "llmath.h"
+class LLVector4a;
+class LLVector2;
class LLMeshOptimizer
{
@@ -36,13 +37,85 @@ public:
LLMeshOptimizer();
~LLMeshOptimizer();
- static void generateShadowIndexBuffer(
+ static void generateShadowIndexBufferU32(
+ U32 *destination,
+ const U32 *indices,
+ U64 index_count,
+ const LLVector4a * vertex_positions,
+ const LLVector4a * normals,
+ const LLVector2 * text_coords,
+ U64 vertex_count);
+
+ static void generateShadowIndexBufferU16(
U16 *destination,
const U16 *indices,
U64 index_count,
- const LLVector4a *vertex_positions,
+ const LLVector4a * vertex_positions,
+ const LLVector4a * normals,
+ const LLVector2 * text_coords,
+ U64 vertex_count);
+
+ static void optimizeVertexCacheU32(
+ U32 *destination,
+ const U32 *indices,
+ U64 index_count,
+ U64 vertex_count);
+
+ static void optimizeVertexCacheU16(
+ U16 *destination,
+ const U16 *indices,
+ U64 index_count,
+ U64 vertex_count);
+
+ // Remap functions
+ // Welds indentical vertexes together.
+ // Removes unused vertices if indices were provided.
+
+ static size_t generateRemapMultiU32(
+ unsigned int* remap,
+ const U32 * indices,
+ U64 index_count,
+ const LLVector4a * vertex_positions,
+ const LLVector4a * normals,
+ const LLVector2 * text_coords,
+ U64 vertex_count);
+
+ static size_t generateRemapMultiU16(
+ unsigned int* remap,
+ const U16 * indices,
+ U64 index_count,
+ const LLVector4a * vertex_positions,
+ const LLVector4a * normals,
+ const LLVector2 * text_coords,
+ U64 vertex_count);
+
+ static void remapIndexBufferU32(U32 * destination_indices,
+ const U32 * indices,
+ U64 index_count,
+ const unsigned int* remap);
+
+ static void remapIndexBufferU16(U16 * destination_indices,
+ const U16 * indices,
+ U64 index_count,
+ const unsigned int* remap);
+
+
+ static void remapPositionsBuffer(LLVector4a * destination_vertices,
+ const LLVector4a * vertex_positions,
U64 vertex_count,
- U64 vertex_positions_stride);
+ const unsigned int* remap);
+
+ static void remapNormalsBuffer(LLVector4a * destination_normalss,
+ const LLVector4a * normals,
+ U64 mormals_count,
+ const unsigned int* remap);
+
+ static void remapUVBuffer(LLVector2 * destination_uvs,
+ const LLVector2 * uv_positions,
+ U64 uv_count,
+ const unsigned int* remap);
+
+ // Simplification
// returns amount of indices in destiantion
// sloppy engages a variant of a mechanizm that does not respect topology as much
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index ae066112c1..33a0b6abdb 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -194,6 +194,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
}
}
+ catch (const LLCoros::Stop&)
+ {
+ LL_DEBUGS("AvNameCache") << "Received a shutdown exception" << LL_ENDL;
+ }
catch (...)
{
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName()
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index 2d460826ff..c5bc37dd0e 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -32,7 +32,6 @@
#include "llcoros.h"
#include "llcorehttputil.h"
#include "lluuid.h"
-#include <boost/smart_ptr/shared_ptr.hpp>
class LLCoprocedurePool;
@@ -84,7 +83,7 @@ public:
private:
- typedef boost::shared_ptr<LLCoprocedurePool> poolPtr_t;
+ typedef std::shared_ptr<LLCoprocedurePool> poolPtr_t;
typedef std::map<std::string, poolPtr_t> poolMap_t;
poolMap_t mPoolMap;
diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp
index 96c1297e0d..b6adc102d2 100644
--- a/indra/llmessage/lldatapacker.cpp
+++ b/indra/llmessage/lldatapacker.cpp
@@ -127,13 +127,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,
total_bits++;
}
- S32 min_val;
U32 max_val;
- if (is_signed)
- {
- min_val = 1 << int_bits;
- min_val *= -1;
- }
max_val = 1 << int_bits;
F32 fixed_val;
diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp
index 53aa35c0f9..6664eb02dc 100644
--- a/indra/llmessage/llpartdata.cpp
+++ b/indra/llmessage/llpartdata.cpp
@@ -311,8 +311,9 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp)
std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
{
s << "Flags: " << std::hex << data.mFlags;
- s << " Pattern: " << std::hex << (U32) data.mPattern << "\n";
- s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
+ s << "Pattern: " << std::hex << (U32) data.mPattern << "\n";
+ s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
+ s << "Particle Age: " << data.mPartData.mMaxAge << "\n";
s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n";
s << "Burst Rate: " << data.mBurstRate << "\n";
s << "Burst Radius: " << data.mBurstRadius << "\n";
diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp
index 7605da4d3f..935af2aa5a 100644
--- a/indra/llmessage/llthrottle.cpp
+++ b/indra/llmessage/llthrottle.cpp
@@ -374,7 +374,6 @@ BOOL LLThrottleGroup::dynamicAdjust()
}
mDynamicAdjustTime = mt_sec;
- S32 total = 0;
// Update historical information
for (i = 0; i < TC_EOF; i++)
{
@@ -391,7 +390,6 @@ BOOL LLThrottleGroup::dynamicAdjust()
}
mBitsSentThisPeriod[i] = 0;
- total += ll_round(mBitsSentHistory[i]);
}
// Look for busy channels
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 219b1855d2..57ea954054 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -666,7 +666,6 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance()
char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock");
char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID");
char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel");
-char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage");
char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats");
char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos");
char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit");
@@ -1047,7 +1046,6 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter");
char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity");
char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket");
-char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket");
char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal");
char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel");
char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing");
@@ -1236,7 +1234,6 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get
char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease");
char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType");
char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply");
-char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData");
char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage");
char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation");
char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection");
@@ -1386,6 +1383,7 @@ char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getIns
char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
char const* const _PREHASH_ParcelEnvironmentBlock = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentBlock");
char const* const _PREHASH_ParcelEnvironmentVersion = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentVersion");
+char const* const _PREHASH_ParcelExtendedFlags = LLMessageStringTable::getInstance()->getString("ParcelExtendedFlags");
char const* const _PREHASH_RegionAllowEnvironmentOverride = LLMessageStringTable::getInstance()->getString("RegionAllowEnvironmentOverride");
char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 8f6ee5a327..572dadd408 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -666,7 +666,6 @@ extern char const* const _PREHASH_GroupRolesCount;
extern char const* const _PREHASH_SimulatorBlock;
extern char const* const _PREHASH_GroupID;
extern char const* const _PREHASH_AgentVel;
-extern char const* const _PREHASH_RequestImage;
extern char const* const _PREHASH_NetStats;
extern char const* const _PREHASH_AgentPos;
extern char const* const _PREHASH_AgentSit;
@@ -1047,7 +1046,6 @@ extern char const* const _PREHASH_SortOrder;
extern char const* const _PREHASH_Hunter;
extern char const* const _PREHASH_SunAngVelocity;
extern char const* const _PREHASH_BinaryBucket;
-extern char const* const _PREHASH_ImagePacket;
extern char const* const _PREHASH_StartGroupProposal;
extern char const* const _PREHASH_EnergyLevel;
extern char const* const _PREHASH_PriceForListing;
@@ -1386,6 +1384,7 @@ extern char const* const _PREHASH_RegionAllowAccessBlock;
extern char const* const _PREHASH_RegionAllowAccessOverride;
extern char const* const _PREHASH_ParcelEnvironmentBlock;
extern char const* const _PREHASH_ParcelEnvironmentVersion;
+extern char const* const _PREHASH_ParcelExtendedFlags;
extern char const* const _PREHASH_RegionAllowEnvironmentOverride;
extern char const* const _PREHASH_UCoord;
extern char const* const _PREHASH_VCoord;
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 6f88232c1d..3e72710366 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -1549,6 +1549,7 @@ void LLPluginClassMedia::seek(float time)
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
message.setValueReal("time", time);
+ mCurrentTime = time; // assume that it worked and we will receive an update later
sendMessage(message);
}
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index adbb93f789..ba76ae4e37 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -335,7 +335,7 @@ public:
// "init_history" message
void initializeUrlHistory(const LLSD& url_history);
- boost::shared_ptr<LLPluginClassMedia> getSharedPrt() { return boost::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this
+ boost::shared_ptr<LLPluginClassMedia> getSharedPtr() { return boost::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this
protected:
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index eef22156bc..1fbbad06d4 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -999,7 +999,7 @@ void LLPluginProcessParent::poll(F64 timeout)
while (itClean != sInstances.end())
{
if ((*itClean).second->isDone())
- sInstances.erase(itClean++);
+ itClean = sInstances.erase(itClean);
else
++itClean;
}
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 7b6d04b096..328b22f900 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -10,15 +10,19 @@ include(LLCoreHttp)
include(LLXML)
include(LLPhysicsExtensions)
include(LLCharacter)
+include(LLRender)
+include(TinyGLTF)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILT_DIR}/include/collada/1.4
${LLCHARACTER_INCLUDE_DIRS}
+ ${TINYGLTF_INCLUDE_DIR}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@@ -28,6 +32,8 @@ include_directories(SYSTEM
set(llprimitive_SOURCE_FILES
lldaeloader.cpp
+ llgltfloader.cpp
+ llgltfmaterial.cpp
llmaterialid.cpp
llmaterial.cpp
llmaterialtable.cpp
@@ -46,6 +52,8 @@ set(llprimitive_SOURCE_FILES
set(llprimitive_HEADER_FILES
CMakeLists.txt
lldaeloader.h
+ llgltfloader.h
+ llgltfmaterial.h
legacy_object_types.h
llmaterial.h
llmaterialid.h
@@ -90,6 +98,7 @@ if (LL_TESTS)
INCLUDE(LLAddBuildTest)
SET(llprimitive_TEST_SOURCE_FILES
llmediaentry.cpp
+ llprimitive.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")
endif (LL_TESTS)
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index e89690438e..73b97cec08 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -2504,20 +2504,6 @@ bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh, LLSD&
return (status == LLModel::NO_ERRORS);
}
-//static
-LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh)
-{
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- LLModel* ret = new LLModel(volume_params, 0.f);
- createVolumeFacesFromDomMesh(ret, mesh);
- if (ret->mLabel.empty())
- {
- ret->mLabel = getElementLabel(mesh);
- }
- return ret;
-}
-
//static diff version supports creating multiple models when material counts spill
// over the 8 face server-side limit
//
@@ -2575,9 +2561,10 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo
ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder);
+ // remove unused/redundant vertices after normalizing
if (!mNoOptimize)
{
- ret->optimizeVolumeFaces();
+ ret->remapVolumeFaces();
}
volume_faces = remainder.size();
@@ -2594,7 +2581,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo
next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod];
next->getVolumeFaces() = remainder;
next->mNormalizedScale = ret->mNormalizedScale;
- next->mNormalizedTranslation = ret->mNormalizedTranslation;
+
if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES)
{
next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end());
@@ -2608,31 +2595,3 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo
return true;
}
-
-bool LLDAELoader::createVolumeFacesFromDomMesh(LLModel* pModel, domMesh* mesh)
-{
- if (mesh)
- {
- pModel->ClearFacesAndMaterials();
-
- LLSD placeholder;
- addVolumeFacesFromDomMesh(pModel, mesh, placeholder);
-
- if (pModel->getNumVolumeFaces() > 0)
- {
- pModel->normalizeVolumeFaces();
- pModel->optimizeVolumeFaces();
-
- if (pModel->getNumVolumeFaces() > 0)
- {
- return true;
- }
- }
- }
- else
- {
- LL_WARNS() << "no mesh found" << LL_ENDL;
- }
-
- return false;
-}
diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h
index 2b211343e1..52ad908870 100644
--- a/indra/llprimitive/lldaeloader.h
+++ b/indra/llprimitive/lldaeloader.h
@@ -90,9 +90,6 @@ protected:
bool verifyController( domController* pController );
static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh, LLSD& log_msg);
- static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh *mesh);
-
- static LLModel* loadModelFromDomMesh(domMesh* mesh);
// Loads a mesh breaking it into one or more models as necessary
// to get around volume face limitations while retaining >8 materials
diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp
new file mode 100644
index 0000000000..6041c9c273
--- /dev/null
+++ b/indra/llprimitive/llgltfloader.cpp
@@ -0,0 +1,402 @@
+/**
+ * @file LLGLTFLoader.cpp
+ * @brief LLGLTFLoader class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llgltfloader.h"
+
+// Import & define single-header gltf import/export lib
+#define TINYGLTF_IMPLEMENTATION
+#define TINYGLTF_USE_CPP14 // default is C++ 11
+
+// tinygltf by default loads image files using STB
+#define STB_IMAGE_IMPLEMENTATION
+// to use our own image loading:
+// 1. replace this definition with TINYGLTF_NO_STB_IMAGE
+// 2. provide image loader callback with TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)
+
+// tinygltf saves image files using STB
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+// similarly, can override with TINYGLTF_NO_STB_IMAGE_WRITE and TinyGLTF::SetImageWriter(fxn, data)
+
+// Additionally, disable inclusion of STB header files entirely with
+// TINYGLTF_NO_INCLUDE_STB_IMAGE
+// TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE
+#include "tinygltf/tiny_gltf.h"
+
+
+// TODO: includes inherited from dae loader. Validate / prune
+
+#include <boost/lexical_cast.hpp>
+
+#include "llsdserialize.h"
+#include "lljoint.h"
+
+#include "glh/glh_linear.h"
+#include "llmatrix4a.h"
+
+#include <boost/regex.hpp>
+#include <boost/algorithm/string/replace.hpp>
+
+static const std::string lod_suffix[LLModel::NUM_LODS] =
+{
+ "_LOD0",
+ "_LOD1",
+ "_LOD2",
+ "",
+ "_PHYS",
+};
+
+
+LLGLTFLoader::LLGLTFLoader(std::string filename,
+ S32 lod,
+ LLModelLoader::load_callback_t load_cb,
+ LLModelLoader::joint_lookup_func_t joint_lookup_func,
+ LLModelLoader::texture_load_func_t texture_load_func,
+ LLModelLoader::state_callback_t state_cb,
+ void * opaque_userdata,
+ JointTransformMap & jointTransformMap,
+ JointNameSet & jointsFromNodes,
+ std::map<std::string, std::string> &jointAliasMap,
+ U32 maxJointsPerMesh,
+ U32 modelLimit) //,
+ //bool preprocess)
+ : LLModelLoader( filename,
+ lod,
+ load_cb,
+ joint_lookup_func,
+ texture_load_func,
+ state_cb,
+ opaque_userdata,
+ jointTransformMap,
+ jointsFromNodes,
+ jointAliasMap,
+ maxJointsPerMesh ),
+ //mPreprocessGLTF(preprocess),
+ mMeshesLoaded(false),
+ mMaterialsLoaded(false)
+{
+}
+
+LLGLTFLoader::~LLGLTFLoader() {}
+
+bool LLGLTFLoader::OpenFile(const std::string &filename)
+{
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ if (std::string::npos == filename.rfind(".gltf"))
+ { // file is binary
+ mGltfLoaded = loader.LoadBinaryFromFile(&mGltfModel, &error_msg, &warn_msg, filename);
+ }
+ else
+ { // file is ascii
+ mGltfLoaded = loader.LoadASCIIFromFile(&mGltfModel, &error_msg, &warn_msg, filename);
+ }
+
+ if (!mGltfLoaded)
+ {
+ if (!warn_msg.empty())
+ LL_WARNS("GLTF_IMPORT") << "gltf load warning: " << warn_msg.c_str() << LL_ENDL;
+ if (!error_msg.empty())
+ LL_WARNS("GLTF_IMPORT") << "gltf load error: " << error_msg.c_str() << LL_ENDL;
+ return false;
+ }
+
+ mMeshesLoaded = parseMeshes();
+ if (mMeshesLoaded) uploadMeshes();
+
+ mMaterialsLoaded = parseMaterials();
+ if (mMaterialsLoaded) uploadMaterials();
+
+ return (mMeshesLoaded || mMaterialsLoaded);
+}
+
+bool LLGLTFLoader::parseMeshes()
+{
+ if (!mGltfLoaded) return false;
+
+ // 2022-04 DJH Volume params from dae example. TODO understand PCODE
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
+
+ for (tinygltf::Mesh mesh : mGltfModel.meshes)
+ {
+ LLModel *pModel = new LLModel(volume_params, 0.f);
+
+ if (populateModelFromMesh(pModel, mesh) &&
+ (LLModel::NO_ERRORS == pModel->getStatus()) &&
+ validate_model(pModel))
+ {
+ mModelList.push_back(pModel);
+ }
+ else
+ {
+ setLoadState(ERROR_MODEL + pModel->getStatus());
+ delete(pModel);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh)
+{
+ pModel->mLabel = mesh.name;
+ int pos_idx, norm_idx, tan_idx, uv0_idx, uv1_idx, color0_idx, color1_idx;
+ tinygltf::Accessor indices_a, positions_a, normals_a, uv0_a, color0_a;
+
+ auto prims = mesh.primitives;
+ for (auto prim : prims)
+ {
+ if (prim.indices >= 0) indices_a = mGltfModel.accessors[prim.indices];
+
+ pos_idx = (prim.attributes.count("POSITION") > 0) ? prim.attributes.at("POSITION") : -1;
+ if (pos_idx >= 0)
+ {
+ positions_a = mGltfModel.accessors[pos_idx];
+ if (TINYGLTF_COMPONENT_TYPE_FLOAT != positions_a.componentType)
+ continue;
+ auto positions_bv = mGltfModel.bufferViews[positions_a.bufferView];
+ auto positions_buf = mGltfModel.buffers[positions_bv.buffer];
+ //auto type = positions_vb.
+ //if (positions_buf.name
+ }
+
+ norm_idx = (prim.attributes.count("NORMAL") > 0) ? prim.attributes.at("NORMAL") : -1;
+ tan_idx = (prim.attributes.count("TANGENT") > 0) ? prim.attributes.at("TANGENT") : -1;
+ uv0_idx = (prim.attributes.count("TEXCOORDS_0") > 0) ? prim.attributes.at("TEXCOORDS_0") : -1;
+ uv1_idx = (prim.attributes.count("TEXCOORDS_1") > 0) ? prim.attributes.at("TEXCOORDS_1") : -1;
+ color0_idx = (prim.attributes.count("COLOR_0") > 0) ? prim.attributes.at("COLOR_0") : -1;
+ color1_idx = (prim.attributes.count("COLOR_1") > 0) ? prim.attributes.at("COLOR_1") : -1;
+
+ if (prim.mode == TINYGLTF_MODE_TRIANGLES)
+ {
+ //auto pos = mesh. TODO resume here DJH 2022-04
+ }
+ }
+
+ //pModel->addFace()
+ return false;
+}
+
+bool LLGLTFLoader::parseMaterials()
+{
+ if (!mGltfLoaded) return false;
+
+ // fill local texture data structures
+ mSamplers.clear();
+ for (auto in_sampler : mGltfModel.samplers)
+ {
+ gltf_sampler sampler;
+ sampler.magFilter = in_sampler.magFilter > 0 ? in_sampler.magFilter : GL_LINEAR;
+ sampler.minFilter = in_sampler.minFilter > 0 ? in_sampler.minFilter : GL_LINEAR;;
+ sampler.wrapS = in_sampler.wrapS;
+ sampler.wrapT = in_sampler.wrapT;
+ sampler.name = in_sampler.name; // unused
+ mSamplers.push_back(sampler);
+ }
+
+ mImages.clear();
+ for (auto in_image : mGltfModel.images)
+ {
+ gltf_image image;
+ image.numChannels = in_image.component;
+ image.bytesPerChannel = in_image.bits >> 3; // Convert bits to bytes
+ image.pixelType = in_image.pixel_type; // Maps exactly, i.e. TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE == GL_UNSIGNED_BYTE, etc
+ image.size = in_image.image.size();
+ image.height = in_image.height;
+ image.width = in_image.width;
+ image.data = in_image.image.data();
+
+ if (in_image.as_is)
+ {
+ LL_WARNS("GLTF_IMPORT") << "Unsupported image encoding" << LL_ENDL;
+ return false;
+ }
+
+ if (image.size != image.height * image.width * image.numChannels * image.bytesPerChannel)
+ {
+ LL_WARNS("GLTF_IMPORT") << "Image size error" << LL_ENDL;
+ return false;
+ }
+
+ mImages.push_back(image);
+ }
+
+ mTextures.clear();
+ for (auto in_tex : mGltfModel.textures)
+ {
+ gltf_texture tex;
+ tex.imageIdx = in_tex.source;
+ tex.samplerIdx = in_tex.sampler;
+ tex.imageUuid.setNull();
+
+ if (tex.imageIdx >= mImages.size() || tex.samplerIdx >= mSamplers.size())
+ {
+ LL_WARNS("GLTF_IMPORT") << "Texture sampler/image index error" << LL_ENDL;
+ return false;
+ }
+
+ mTextures.push_back(tex);
+ }
+
+ // parse each material
+ for (tinygltf::Material gltf_material : mGltfModel.materials)
+ {
+ gltf_render_material mat;
+ mat.name = gltf_material.name;
+
+ tinygltf::PbrMetallicRoughness& pbr = gltf_material.pbrMetallicRoughness;
+ mat.hasPBR = true; // Always true, for now
+
+ mat.baseColor.set(pbr.baseColorFactor.data());
+ mat.hasBaseTex = pbr.baseColorTexture.index >= 0;
+ mat.baseColorTexIdx = pbr.baseColorTexture.index;
+ mat.baseColorTexCoords = pbr.baseColorTexture.texCoord;
+
+ mat.metalness = pbr.metallicFactor;
+ mat.roughness = pbr.roughnessFactor;
+ mat.hasMRTex = pbr.metallicRoughnessTexture.index >= 0;
+ mat.metalRoughTexIdx = pbr.metallicRoughnessTexture.index;
+ mat.metalRoughTexCoords = pbr.metallicRoughnessTexture.texCoord;
+
+ mat.normalScale = gltf_material.normalTexture.scale;
+ mat.hasNormalTex = gltf_material.normalTexture.index >= 0;
+ mat.normalTexIdx = gltf_material.normalTexture.index;
+ mat.normalTexCoords = gltf_material.normalTexture.texCoord;
+
+ mat.occlusionScale = gltf_material.occlusionTexture.strength;
+ mat.hasOcclusionTex = gltf_material.occlusionTexture.index >= 0;
+ mat.occlusionTexIdx = gltf_material.occlusionTexture.index;
+ mat.occlusionTexCoords = gltf_material.occlusionTexture.texCoord;
+
+ mat.emissiveColor.set(gltf_material.emissiveFactor.data());
+ mat.hasEmissiveTex = gltf_material.emissiveTexture.index >= 0;
+ mat.emissiveTexIdx = gltf_material.emissiveTexture.index;
+ mat.emissiveTexCoords = gltf_material.emissiveTexture.texCoord;
+
+ mat.alphaMode = gltf_material.alphaMode;
+ mat.alphaMask = gltf_material.alphaCutoff;
+
+ if ((mat.hasNormalTex && (mat.normalTexIdx >= mTextures.size())) ||
+ (mat.hasOcclusionTex && (mat.occlusionTexIdx >= mTextures.size())) ||
+ (mat.hasEmissiveTex && (mat.emissiveTexIdx >= mTextures.size())) ||
+ (mat.hasBaseTex && (mat.baseColorTexIdx >= mTextures.size())) ||
+ (mat.hasMRTex && (mat.metalRoughTexIdx >= mTextures.size())))
+ {
+ LL_WARNS("GLTF_IMPORT") << "Texture resource index error" << LL_ENDL;
+ return false;
+ }
+
+ if ((mat.hasNormalTex && (mat.normalTexCoords > 2)) || // mesh can have up to 3 sets of UV
+ (mat.hasOcclusionTex && (mat.occlusionTexCoords > 2)) ||
+ (mat.hasEmissiveTex && (mat.emissiveTexCoords > 2)) ||
+ (mat.hasBaseTex && (mat.baseColorTexCoords > 2)) ||
+ (mat.hasMRTex && (mat.metalRoughTexCoords > 2)))
+ {
+ LL_WARNS("GLTF_IMPORT") << "Image texcoord index error" << LL_ENDL;
+ return false;
+ }
+
+ mMaterials.push_back(mat);
+ }
+
+ return true;
+}
+
+// TODO: convert raw vertex buffers to UUIDs
+void LLGLTFLoader::uploadMeshes()
+{
+ llassert(0);
+}
+
+// convert raw image buffers to texture UUIDs & assemble into a render material
+void LLGLTFLoader::uploadMaterials()
+{
+ for (gltf_render_material mat : mMaterials) // Initially 1 material per gltf file, but design for multiple
+ {
+ if (mat.hasBaseTex)
+ {
+ gltf_texture& gtex = mTextures[mat.baseColorTexIdx];
+ if (gtex.imageUuid.isNull())
+ {
+ gtex.imageUuid = imageBufferToTextureUUID(gtex);
+ }
+ }
+
+ if (mat.hasMRTex)
+ {
+ gltf_texture& gtex = mTextures[mat.metalRoughTexIdx];
+ if (gtex.imageUuid.isNull())
+ {
+ gtex.imageUuid = imageBufferToTextureUUID(gtex);
+ }
+ }
+
+ if (mat.hasNormalTex)
+ {
+ gltf_texture& gtex = mTextures[mat.normalTexIdx];
+ if (gtex.imageUuid.isNull())
+ {
+ gtex.imageUuid = imageBufferToTextureUUID(gtex);
+ }
+ }
+
+ if (mat.hasOcclusionTex)
+ {
+ gltf_texture& gtex = mTextures[mat.occlusionTexIdx];
+ if (gtex.imageUuid.isNull())
+ {
+ gtex.imageUuid = imageBufferToTextureUUID(gtex);
+ }
+ }
+
+ if (mat.hasEmissiveTex)
+ {
+ gltf_texture& gtex = mTextures[mat.emissiveTexIdx];
+ if (gtex.imageUuid.isNull())
+ {
+ gtex.imageUuid = imageBufferToTextureUUID(gtex);
+ }
+ }
+ }
+}
+
+LLUUID LLGLTFLoader::imageBufferToTextureUUID(const gltf_texture& tex)
+{
+ //gltf_image& image = mImages[tex.imageIdx];
+ //gltf_sampler& sampler = mSamplers[tex.samplerIdx];
+
+ // fill an LLSD container with image+sampler data
+
+ // upload texture
+
+ // retrieve UUID
+
+ return LLUUID::null;
+}
diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h
new file mode 100644
index 0000000000..b4d6ca1940
--- /dev/null
+++ b/indra/llprimitive/llgltfloader.h
@@ -0,0 +1,206 @@
+/**
+ * @file LLGLTFLoader.h
+ * @brief LLGLTFLoader class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLGLTFLoader_H
+#define LL_LLGLTFLoader_H
+
+#include "tinygltf/tiny_gltf.h"
+
+#include "llglheaders.h"
+#include "llmodelloader.h"
+
+// gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD
+
+class gltf_sampler
+{
+public:
+ // Uses GL enums
+ S32 minFilter; // GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR
+ S32 magFilter; // GL_NEAREST or GL_LINEAR
+ S32 wrapS; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT
+ S32 wrapT; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT
+ //S32 wrapR; // Found in some sample files, but not part of glTF 2.0 spec. Ignored.
+ std::string name; // optional, currently unused
+ // extensions and extras are sampler optional fields that we don't support - at least initially
+};
+
+class gltf_image
+{
+public:// Note that glTF images are defined with row 0 at the top (opposite of OpenGL)
+ U8* data; // ptr to decoded image data
+ U32 size; // in bytes, regardless of channel width
+ U32 width;
+ U32 height;
+ U32 numChannels; // range 1..4
+ U32 bytesPerChannel; // converted from gltf "bits", expects only 8, 16 or 32 as input
+ U32 pixelType; // one of (TINYGLTF_COMPONENT_TYPE)_UNSIGNED_BYTE, _UNSIGNED_SHORT, _UNSIGNED_INT, or _FLOAT
+};
+
+class gltf_texture
+{
+public:
+ U32 imageIdx;
+ U32 samplerIdx;
+ LLUUID imageUuid = LLUUID::null;
+};
+
+class gltf_render_material
+{
+public:
+ std::string name;
+
+ // scalar values
+ LLColor4 baseColor; // linear encoding. Multiplied with vertex color, if present.
+ double metalness;
+ double roughness;
+ double normalScale; // scale applies only to X,Y components of normal
+ double occlusionScale; // strength multiplier for occlusion
+ LLColor4 emissiveColor; // emissive mulitiplier, assumed linear encoding (spec 2.0 is silent)
+ std::string alphaMode; // "OPAQUE", "MASK" or "BLEND"
+ double alphaMask; // alpha cut-off
+
+ // textures
+ U32 baseColorTexIdx; // always sRGB encoded
+ U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel
+ U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0)
+ U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded
+ U32 emissiveTexIdx; // always stored as sRGB, in nits (candela / meter^2)
+
+ // texture coordinates
+ U32 baseColorTexCoords;
+ U32 metalRoughTexCoords;
+ U32 normalTexCoords;
+ U32 occlusionTexCoords;
+ U32 emissiveTexCoords;
+
+ // TODO: Add traditional (diffuse, normal, specular) UUIDs here, or add this struct to LL_TextureEntry??
+
+ bool hasPBR;
+ bool hasBaseTex, hasMRTex, hasNormalTex, hasOcclusionTex, hasEmissiveTex;
+
+ // This field is populated after upload
+ LLUUID material_uuid = LLUUID::null;
+
+};
+
+class gltf_mesh
+{
+public:
+ std::string name;
+
+ // TODO add mesh import DJH 2022-04
+
+};
+
+class LLGLTFLoader : public LLModelLoader
+{
+ public:
+ typedef std::map<std::string, LLImportMaterial> material_map;
+
+ LLGLTFLoader(std::string filename,
+ S32 lod,
+ LLModelLoader::load_callback_t load_cb,
+ LLModelLoader::joint_lookup_func_t joint_lookup_func,
+ LLModelLoader::texture_load_func_t texture_load_func,
+ LLModelLoader::state_callback_t state_cb,
+ void * opaque_userdata,
+ JointTransformMap & jointTransformMap,
+ JointNameSet & jointsFromNodes,
+ std::map<std::string, std::string> &jointAliasMap,
+ U32 maxJointsPerMesh,
+ U32 modelLimit); //,
+ //bool preprocess );
+ virtual ~LLGLTFLoader();
+
+ virtual bool OpenFile(const std::string &filename);
+
+protected:
+ tinygltf::Model mGltfModel;
+ bool mGltfLoaded;
+ bool mMeshesLoaded;
+ bool mMaterialsLoaded;
+
+ std::vector<gltf_mesh> mMeshes;
+ std::vector<gltf_render_material> mMaterials;
+
+ std::vector<gltf_texture> mTextures;
+ std::vector<gltf_image> mImages;
+ std::vector<gltf_sampler> mSamplers;
+
+private:
+ bool parseMeshes();
+ void uploadMeshes();
+ bool parseMaterials();
+ void uploadMaterials();
+ bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh);
+ LLUUID imageBufferToTextureUUID(const gltf_texture& tex);
+
+ // bool mPreprocessGLTF;
+
+ /* Below inherited from dae loader - unknown if/how useful here
+
+ void processElement(gltfElement *element, bool &badElement, GLTF *gltf);
+ void processGltfModel(LLModel *model, GLTF *gltf, gltfElement *pRoot, gltfMesh *mesh, gltfSkin *skin);
+
+ material_map getMaterials(LLModel *model, gltfInstance_geometry *instance_geo, GLTF *gltf);
+ LLImportMaterial profileToMaterial(gltfProfile_COMMON *material, GLTF *gltf);
+ LLColor4 getGltfColor(gltfElement *element);
+
+ gltfElement *getChildFromElement(gltfElement *pElement, std::string const &name);
+
+ bool isNodeAJoint(gltfNode *pNode);
+ void processJointNode(gltfNode *pNode, std::map<std::string, LLMatrix4> &jointTransforms);
+ void extractTranslation(gltfTranslate *pTranslate, LLMatrix4 &transform);
+ void extractTranslationViaElement(gltfElement *pTranslateElement, LLMatrix4 &transform);
+ void extractTranslationViaSID(gltfElement *pElement, LLMatrix4 &transform);
+ void buildJointToNodeMappingFromScene(gltfElement *pRoot);
+ void processJointToNodeMapping(gltfNode *pNode);
+ void processChildJoints(gltfNode *pParentNode);
+
+ bool verifyCount(int expected, int result);
+
+ // Verify that a controller matches vertex counts
+ bool verifyController(gltfController *pController);
+
+ static bool addVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh, LLSD &log_msg);
+ static bool createVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh);
+
+ static LLModel *loadModelFromGltfMesh(gltfMesh *mesh);
+
+ // Loads a mesh breaking it into one or more models as necessary
+ // to get around volume face limitations while retaining >8 materials
+ //
+ bool loadModelsFromGltfMesh(gltfMesh *mesh, std::vector<LLModel *> &models_out, U32 submodel_limit);
+
+ static std::string getElementLabel(gltfElement *element);
+ static size_t getSuffixPosition(std::string label);
+ static std::string getLodlessLabel(gltfElement *element);
+
+ static std::string preprocessGLTF(std::string filename);
+ */
+
+};
+#endif // LL_LLGLTFLLOADER_H
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
new file mode 100644
index 0000000000..7b6612b90a
--- /dev/null
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -0,0 +1,557 @@
+/**
+ * @file llgltfmaterial.cpp
+ * @brief Material definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llgltfmaterial.h"
+
+#include "tinygltf/tiny_gltf.h"
+
+LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs)
+{
+ *this = rhs;
+}
+
+LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
+{
+ //have to do a manual operator= because of LLRefCount
+ mBaseColorId = rhs.mBaseColorId;
+ mNormalId = rhs.mNormalId;
+ mMetallicRoughnessId = rhs.mMetallicRoughnessId;
+ mEmissiveId = rhs.mEmissiveId;
+
+ mBaseColor = rhs.mBaseColor;
+ mEmissiveColor = rhs.mEmissiveColor;
+
+ mMetallicFactor = rhs.mMetallicFactor;
+ mRoughnessFactor = rhs.mRoughnessFactor;
+ mAlphaCutoff = rhs.mAlphaCutoff;
+
+ mDoubleSided = rhs.mDoubleSided;
+ mAlphaMode = rhs.mAlphaMode;
+
+ mTextureTransform = rhs.mTextureTransform;
+
+ return *this;
+}
+
+bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg)
+{
+#if 1
+ tinygltf::TinyGLTF gltf;
+
+ tinygltf::Model model_in;
+
+ if (gltf.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, json.c_str(), json.length(), ""))
+ {
+ setFromModel(model_in, 0);
+
+ //DEBUG generate json and print
+ LL_INFOS() << asJSON(true) << LL_ENDL;
+
+ return true;
+ }
+#endif
+ return false;
+}
+
+std::string LLGLTFMaterial::asJSON(bool prettyprint) const
+{
+#if 1
+ tinygltf::TinyGLTF gltf;
+ tinygltf::Model model_out;
+
+ std::ostringstream str;
+
+ writeToModel(model_out, 0);
+
+ gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false);
+
+ return str.str();
+#else
+ return "";
+#endif
+}
+
+void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index)
+{
+ if (model.materials.size() <= mat_index)
+ {
+ return;
+ }
+
+ const tinygltf::Material& material_in = model.materials[mat_index];
+
+ // get base color texture
+ S32 tex_index = material_in.pbrMetallicRoughness.baseColorTexture.index;
+ if (tex_index >= 0)
+ {
+ mBaseColorId.set(model.images[tex_index].uri);
+ }
+ else
+ {
+ mBaseColorId.setNull();
+ }
+
+ // get normal map
+ tex_index = material_in.normalTexture.index;
+ if (tex_index >= 0)
+ {
+ mNormalId.set(model.images[tex_index].uri);
+ }
+ else
+ {
+ mNormalId.setNull();
+ }
+
+ // get metallic-roughness texture
+ tex_index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (tex_index >= 0)
+ {
+ mMetallicRoughnessId.set(model.images[tex_index].uri);
+ }
+ else
+ {
+ mMetallicRoughnessId.setNull();
+ }
+
+ // get emissive texture
+ tex_index = material_in.emissiveTexture.index;
+ if (tex_index >= 0)
+ {
+ mEmissiveId.set(model.images[tex_index].uri);
+ }
+ else
+ {
+ mEmissiveId.setNull();
+ }
+
+ setAlphaMode(material_in.alphaMode);
+ mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f);
+
+ mBaseColor.set(material_in.pbrMetallicRoughness.baseColorFactor);
+ mEmissiveColor.set(material_in.emissiveFactor);
+
+ mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f);
+ mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f);
+
+ mDoubleSided = material_in.doubleSided;
+}
+
+void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
+{
+ if (model.materials.size() < mat_index + 1)
+ {
+ model.materials.resize(mat_index + 1);
+ }
+
+ tinygltf::Material& material_out = model.materials[mat_index];
+
+ // set base color texture
+ if (mBaseColorId.notNull())
+ {
+ U32 idx = model.images.size();
+ model.images.resize(idx + 1);
+ model.textures.resize(idx + 1);
+
+ material_out.pbrMetallicRoughness.baseColorTexture.index = idx;
+ model.textures[idx].source = idx;
+ model.images[idx].uri = mBaseColorId.asString();
+ }
+
+ // set normal texture
+ if (mNormalId.notNull())
+ {
+ U32 idx = model.images.size();
+ model.images.resize(idx + 1);
+ model.textures.resize(idx + 1);
+
+ material_out.normalTexture.index = idx;
+ model.textures[idx].source = idx;
+ model.images[idx].uri = mNormalId.asString();
+ }
+
+ // set metallic-roughness texture
+ if (mMetallicRoughnessId.notNull())
+ {
+ U32 idx = model.images.size();
+ model.images.resize(idx + 1);
+ model.textures.resize(idx + 1);
+
+ material_out.pbrMetallicRoughness.metallicRoughnessTexture.index = idx;
+ model.textures[idx].source = idx;
+ model.images[idx].uri = mMetallicRoughnessId.asString();
+ }
+
+ // set emissive texture
+ if (mEmissiveId.notNull())
+ {
+ U32 idx = model.images.size();
+ model.images.resize(idx + 1);
+ model.textures.resize(idx + 1);
+
+ material_out.emissiveTexture.index = idx;
+ model.textures[idx].source = idx;
+ model.images[idx].uri = mEmissiveId.asString();
+ }
+
+ material_out.alphaMode = getAlphaMode();
+ material_out.alphaCutoff = mAlphaCutoff;
+
+ mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor);
+ mEmissiveColor.write(material_out.emissiveFactor);
+
+ material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor;
+ material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor;
+
+ material_out.doubleSided = mDoubleSided;
+
+ model.asset.version = "2.0";
+}
+
+
+void LLGLTFMaterial::setBaseColorId(const LLUUID& id)
+{
+ mBaseColorId = id;
+}
+
+void LLGLTFMaterial::setNormalId(const LLUUID& id)
+{
+ mNormalId = id;
+}
+
+void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id)
+{
+ mMetallicRoughnessId = id;
+}
+
+void LLGLTFMaterial::setEmissiveId(const LLUUID& id)
+{
+ mEmissiveId = id;
+}
+
+void LLGLTFMaterial::setBaseColorFactor(const LLColor3& baseColor, F32 transparency)
+{
+ mBaseColor.set(baseColor, transparency);
+ mBaseColor.clamp();
+}
+
+void LLGLTFMaterial::setAlphaCutoff(F32 cutoff)
+{
+ mAlphaCutoff = llclamp(cutoff, 0.f, 1.f);
+}
+
+void LLGLTFMaterial::setEmissiveColorFactor(const LLColor3& emissiveColor)
+{
+ mEmissiveColor = emissiveColor;
+ mEmissiveColor.clamp();
+}
+
+void LLGLTFMaterial::setMetallicFactor(F32 metallic)
+{
+ mMetallicFactor = llclamp(metallic, 0.f, 1.f);
+}
+
+void LLGLTFMaterial::setRoughnessFactor(F32 roughness)
+{
+ mRoughnessFactor = llclamp(roughness, 0.f, 1.f);
+}
+
+void LLGLTFMaterial::setAlphaMode(S32 mode)
+{
+ mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK);
+}
+
+void LLGLTFMaterial::setDoubleSided(bool double_sided)
+{
+ // sure, no clamping will ever be needed for a bool, but include the
+ // setter for consistency with the clamping API
+ mDoubleSided = double_sided;
+}
+
+void LLGLTFMaterial::setTextureOffset(TextureInfo texture_info, const LLVector2& offset)
+{
+ mTextureTransform[texture_info].mOffset = offset;
+}
+
+void LLGLTFMaterial::setTextureScale(TextureInfo texture_info, const LLVector2& scale)
+{
+ mTextureTransform[texture_info].mScale = scale;
+}
+
+void LLGLTFMaterial::setTextureRotation(TextureInfo texture_info, float rotation)
+{
+ mTextureTransform[texture_info].mRotation = rotation;
+}
+
+// Default value accessors
+
+LLUUID LLGLTFMaterial::getDefaultBaseColorId()
+{
+ return LLUUID::null;
+}
+
+LLUUID LLGLTFMaterial::getDefaultNormalId()
+{
+ return LLUUID::null;
+}
+
+LLUUID LLGLTFMaterial::getDefaultEmissiveId()
+{
+ return LLUUID::null;
+}
+
+LLUUID LLGLTFMaterial::getDefaultMetallicRoughnessId()
+{
+ return LLUUID::null;
+}
+
+F32 LLGLTFMaterial::getDefaultAlphaCutoff()
+{
+ return 0.f;
+}
+
+S32 LLGLTFMaterial::getDefaultAlphaMode()
+{
+ return (S32) ALPHA_MODE_OPAQUE;
+}
+
+F32 LLGLTFMaterial::getDefaultMetallicFactor()
+{
+ return 0.f;
+}
+
+F32 LLGLTFMaterial::getDefaultRoughnessFactor()
+{
+ return 0.f;
+}
+
+LLColor4 LLGLTFMaterial::getDefaultBaseColor()
+{
+ return LLColor4::white;
+}
+
+LLColor3 LLGLTFMaterial::getDefaultEmissiveColor()
+{
+ return LLColor3::black;
+}
+
+bool LLGLTFMaterial::getDefaultDoubleSided()
+{
+ return false;
+}
+
+LLVector2 LLGLTFMaterial::getDefaultTextureOffset()
+{
+ return LLVector2(0.f, 0.f);
+}
+
+LLVector2 LLGLTFMaterial::getDefaultTextureScale()
+{
+ return LLVector2(1.f, 1.f);
+}
+
+F32 LLGLTFMaterial::getDefaultTextureRotation()
+{
+ return 0.f;
+}
+
+void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const
+{
+ if (model.materials.size() < mat_index + 1)
+ {
+ model.materials.resize(mat_index + 1);
+ }
+
+ tinygltf::Material& material_out = model.materials[mat_index];
+
+ // TODO - fix handling of resetting to null/default values
+
+ // set base color texture
+ if (mBaseColorId.notNull() && mBaseColorId != base_material->mBaseColorId)
+ {
+ U32 idx = model.images.size();
+ model.images.resize(idx + 1);
+ model.textures.resize(idx + 1);
+
+ material_out.pbrMetallicRoughness.baseColorTexture.index = idx;
+ model.textures[idx].source = idx;
+ model.images[idx].uri = mBaseColorId.asString();
+ }
+
+ // set normal texture
+ if (mNormalId.notNull() && mNormalId != base_material->mNormalId)
+ {
+ U32 idx = model.images.size();
+ model.images.resize(idx + 1);
+ model.textures.resize(idx + 1);
+
+ material_out.normalTexture.index = idx;
+ model.textures[idx].source = idx;
+ model.images[idx].uri = mNormalId.asString();
+ }
+
+ // set metallic-roughness texture
+ if (mMetallicRoughnessId.notNull() && mMetallicRoughnessId != base_material->mMetallicRoughnessId)
+ {
+ U32 idx = model.images.size();
+ model.images.resize(idx + 1);
+ model.textures.resize(idx + 1);
+
+ material_out.pbrMetallicRoughness.metallicRoughnessTexture.index = idx;
+ model.textures[idx].source = idx;
+ model.images[idx].uri = mMetallicRoughnessId.asString();
+ }
+
+ // set emissive texture
+ if (mEmissiveId.notNull() && mEmissiveId != base_material->mEmissiveId)
+ {
+ U32 idx = model.images.size();
+ model.images.resize(idx + 1);
+ model.textures.resize(idx + 1);
+
+ material_out.emissiveTexture.index = idx;
+ model.textures[idx].source = idx;
+ model.images[idx].uri = mEmissiveId.asString();
+ }
+
+ if (mAlphaMode != base_material->mAlphaMode)
+ {
+ material_out.alphaMode = getAlphaMode();
+ }
+
+ if (mAlphaCutoff != base_material->mAlphaCutoff)
+ {
+ material_out.alphaCutoff = mAlphaCutoff;
+ }
+
+ if (mBaseColor != base_material->mBaseColor)
+ {
+ mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor);
+ }
+
+ if (mEmissiveColor != base_material->mEmissiveColor)
+ {
+ mEmissiveColor.write(material_out.emissiveFactor);
+ }
+
+ if (mMetallicFactor != base_material->mMetallicFactor)
+ {
+ material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor;
+ }
+
+ if (mRoughnessFactor != base_material->mRoughnessFactor)
+ {
+ material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor;
+ }
+
+ if (mDoubleSided != base_material->mDoubleSided)
+ {
+ material_out.doubleSided = mDoubleSided;
+ }
+}
+
+void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
+{
+ // TODO: potentially reimplement this with a more general purpose JSON merge
+
+ if (override_mat.mBaseColorId != getDefaultBaseColorId())
+ {
+ mBaseColorId = override_mat.mBaseColorId;
+ }
+
+ if (override_mat.mNormalId != getDefaultNormalId())
+ {
+ mNormalId = override_mat.mNormalId;
+ }
+
+ if (override_mat.mMetallicRoughnessId != getDefaultMetallicRoughnessId())
+ {
+ mMetallicRoughnessId = override_mat.mMetallicRoughnessId;
+ }
+
+ if (override_mat.mEmissiveId != getDefaultEmissiveId())
+ {
+ mEmissiveId = override_mat.mEmissiveId;
+ }
+
+ if (override_mat.mBaseColor != getDefaultBaseColor())
+ {
+ mBaseColor = override_mat.mBaseColor;
+ }
+
+ if (override_mat.mEmissiveColor != getDefaultEmissiveColor())
+ {
+ mEmissiveColor = override_mat.mEmissiveColor;
+ }
+
+ if (override_mat.mMetallicFactor != getDefaultMetallicFactor())
+ {
+ mMetallicFactor = override_mat.mMetallicFactor;
+ }
+
+ if (override_mat.mRoughnessFactor != getDefaultRoughnessFactor())
+ {
+ mRoughnessFactor = override_mat.mRoughnessFactor;
+ }
+
+ if (override_mat.mAlphaMode != getDefaultAlphaMode())
+ {
+ mAlphaMode = override_mat.mAlphaMode;
+ }
+ if (override_mat.mAlphaCutoff != getDefaultAlphaCutoff())
+ {
+ mAlphaCutoff = override_mat.mAlphaCutoff;
+ }
+
+ if (override_mat.mDoubleSided != getDefaultDoubleSided())
+ {
+ mDoubleSided = override_mat.mDoubleSided;
+ }
+
+ for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (override_mat.mTextureTransform[i].mOffset != getDefaultTextureOffset())
+ {
+ mTextureTransform[i].mOffset = override_mat.mTextureTransform[i].mOffset;
+ }
+
+ if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale())
+ {
+ mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale;
+ }
+
+ if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale())
+ {
+ mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale;
+ }
+
+ if (override_mat.mTextureTransform[i].mRotation != getDefaultTextureRotation())
+ {
+ mTextureTransform[i].mRotation = override_mat.mTextureTransform[i].mRotation;
+ }
+ }
+}
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
new file mode 100644
index 0000000000..ea7e402805
--- /dev/null
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -0,0 +1,193 @@
+/**
+ * @file llgltfmaterial.h
+ * @brief Material definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#pragma once
+
+#include "llrefcount.h"
+#include "llmemory.h"
+#include "v4color.h"
+#include "v3color.h"
+#include "v2math.h"
+#include "lluuid.h"
+#include "llmd5.h"
+
+#include <string>
+
+namespace tinygltf
+{
+ class Model;
+}
+
+class LLGLTFMaterial : public LLRefCount
+{
+public:
+
+ struct TextureTransform
+ {
+ LLVector2 mOffset = { 0.f, 0.f };
+ LLVector2 mScale = { 1.f, 1.f };
+ F32 mRotation = 0.f;
+ };
+
+ enum AlphaMode
+ {
+ ALPHA_MODE_OPAQUE = 0,
+ ALPHA_MODE_BLEND,
+ ALPHA_MODE_MASK
+ };
+
+ LLGLTFMaterial() {}
+ LLGLTFMaterial(const LLGLTFMaterial& rhs);
+
+ LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs);
+
+ LLUUID mBaseColorId;
+ LLUUID mNormalId;
+ LLUUID mMetallicRoughnessId;
+ LLUUID mEmissiveId;
+
+ LLColor4 mBaseColor = LLColor4(1, 1, 1, 1);
+ LLColor3 mEmissiveColor = LLColor3(0, 0, 0);
+
+ F32 mMetallicFactor = 0.f;
+ F32 mRoughnessFactor = 0.f;
+ F32 mAlphaCutoff = 0.f;
+
+ bool mDoubleSided = false;
+ AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE;
+
+ // get a UUID based on a hash of this LLGLTFMaterial
+ LLUUID getHash() const
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ LLMD5 md5;
+ md5.update((unsigned char*)this, sizeof(this));
+ md5.finalize();
+ LLUUID id;
+ md5.raw_digest(id.mData);
+ // *TODO: Hash the overrides
+ return id;
+ }
+
+ enum TextureInfo : U32
+ {
+ GLTF_TEXTURE_INFO_BASE_COLOR,
+ GLTF_TEXTURE_INFO_NORMAL,
+ GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS,
+ GLTF_TEXTURE_INFO_EMISSIVE,
+
+ GLTF_TEXTURE_INFO_COUNT
+ };
+
+ std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
+
+ //setters for various members (will clamp to acceptable ranges)
+
+ void setBaseColorId(const LLUUID& id);
+ void setNormalId(const LLUUID& id);
+ void setMetallicRoughnessId(const LLUUID& id);
+ void setEmissiveId(const LLUUID& id);
+
+ void setBaseColorFactor(const LLColor3& baseColor, F32 transparency);
+ void setAlphaCutoff(F32 cutoff);
+ void setEmissiveColorFactor(const LLColor3& emissiveColor);
+ void setMetallicFactor(F32 metallic);
+ void setRoughnessFactor(F32 roughness);
+ void setAlphaMode(S32 mode);
+ void setDoubleSided(bool double_sided);
+ void setTextureOffset(TextureInfo texture_info, const LLVector2& offset);
+ void setTextureScale(TextureInfo texture_info, const LLVector2& scale);
+ void setTextureRotation(TextureInfo texture_info, float rotation);
+
+ // Default value accessors
+ static LLUUID getDefaultBaseColorId();
+ static LLUUID getDefaultNormalId();
+ static LLUUID getDefaultEmissiveId();
+ static LLUUID getDefaultMetallicRoughnessId();
+ static F32 getDefaultAlphaCutoff();
+ static S32 getDefaultAlphaMode();
+ static F32 getDefaultMetallicFactor();
+ static F32 getDefaultRoughnessFactor();
+ static LLColor4 getDefaultBaseColor();
+ static LLColor3 getDefaultEmissiveColor();
+ static bool getDefaultDoubleSided();
+ static LLVector2 getDefaultTextureOffset();
+ static LLVector2 getDefaultTextureScale();
+ static F32 getDefaultTextureRotation();
+
+ // set mAlphaMode from string.
+ // Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE
+ void setAlphaMode(const std::string& mode)
+ {
+ if (mode == "MASK")
+ {
+ mAlphaMode = ALPHA_MODE_MASK;
+ }
+ else if (mode == "BLEND")
+ {
+ mAlphaMode = ALPHA_MODE_BLEND;
+ }
+ else
+ {
+ mAlphaMode = ALPHA_MODE_OPAQUE;
+ }
+ }
+
+ const char* getAlphaMode() const
+ {
+ switch (mAlphaMode)
+ {
+ case ALPHA_MODE_MASK: return "MASK";
+ case ALPHA_MODE_BLEND: return "BLEND";
+ default: return "OPAQUE";
+ }
+ }
+
+ // set the contents of this LLGLTFMaterial from the given json
+ // returns true if successful
+ // json - the json text to load from
+ // warn_msg - warning message from TinyGLTF if any
+ // error_msg - error_msg from TinyGLTF if any
+ bool fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg);
+
+ // get the contents of this LLGLTFMaterial as a json string
+ std::string asJSON(bool prettyprint = false) const;
+
+ // initialize from given tinygltf::Model
+ // model - the model to reference
+ // mat_index - index of material in model's material array
+ void setFromModel(const tinygltf::Model& model, S32 mat_index);
+
+ // write to given tinygltf::Model
+ void writeToModel(tinygltf::Model& model, S32 mat_index) const;
+
+ // calculate the fields in this material that differ from a base material and write them out to a given tinygltf::Model
+ void writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const;
+
+ void applyOverride(const LLGLTFMaterial& override_mat);
+
+};
+
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index a219ac1450..f546ac1645 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -331,6 +331,17 @@ void LLMaterial::setAlphaMaskCutoff(U8 cutoff)
mAlphaMaskCutoff = cutoff;
}
+LLUUID LLMaterial::getMaterialID() const
+{
+ // TODO - not null
+ return LLUUID::null;
+}
+
+void LLMaterial::setMaterialID(const LLUUID &material_id)
+{
+ // TODO - set
+}
+
LLSD LLMaterial::asLLSD() const
{
LLSD material_data;
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
index d58b7ee812..2f8aafc2cf 100644
--- a/indra/llprimitive/llmaterial.h
+++ b/indra/llprimitive/llmaterial.h
@@ -27,8 +27,6 @@
#ifndef LL_LLMATERIAL_H
#define LL_LLMATERIAL_H
-#include <boost/shared_ptr.hpp>
-
#include "llmaterialid.h"
#include "llsd.h"
#include "v4coloru.h"
@@ -54,8 +52,6 @@ public:
ALPHA_SHADER_COUNT = 4
} eShaderCount;
-
-
static const U8 DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255));
static const LLColor4U DEFAULT_SPECULAR_LIGHT_COLOR;
static const U8 DEFAULT_ENV_INTENSITY = 0;
@@ -119,6 +115,8 @@ public:
void setDiffuseAlphaMode(U8 alpha_mode);
U8 getAlphaMaskCutoff() const;
void setAlphaMaskCutoff(U8 cutoff);
+ LLUUID getMaterialID() const;
+ void setMaterialID(LLUUID const & material_id);
bool isNull() const;
static const LLMaterial null;
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp
index f88a607c4f..340a83801c 100644
--- a/indra/llprimitive/llmaterialid.cpp
+++ b/indra/llprimitive/llmaterialid.cpp
@@ -155,6 +155,13 @@ std::string LLMaterialID::asString() const
return materialIDString;
}
+LLUUID LLMaterialID::asUUID() const
+{
+ LLUUID ret;
+ memcpy(ret.mData, mID, MATERIAL_ID_SIZE);
+ return ret;
+}
+
std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
{
s << material_id.asString();
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h
index ee663f8f99..e6165dfc91 100644
--- a/indra/llprimitive/llmaterialid.h
+++ b/indra/llprimitive/llmaterialid.h
@@ -61,6 +61,7 @@ public:
LLSD asLLSD() const;
std::string asString() const;
+ LLUUID asUUID() const;
friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id);
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 204ff63712..206142fdd5 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -36,7 +36,7 @@
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
-# include "zlib/zlib.h"
+# include "zlib-ng/zlib.h"
#endif
std::string model_names[] =
@@ -53,7 +53,6 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
LLModel::LLModel(LLVolumeParams& params, F32 detail)
: LLVolume(params, detail),
mNormalizedScale(1,1,1),
- mNormalizedTranslation(0,0,0),
mPelvisOffset( 0.0f ),
mStatus(NO_ERRORS),
mSubmodelID(0)
@@ -107,6 +106,14 @@ void LLModel::offsetMesh( const LLVector3& pivotPoint )
}
}
+void LLModel::remapVolumeFaces()
+{
+ for (U32 i = 0; i < getNumVolumeFaces(); ++i)
+ {
+ mVolumeFaces[i].remap();
+ }
+}
+
void LLModel::optimizeVolumeFaces()
{
for (U32 i = 0; i < getNumVolumeFaces(); ++i)
@@ -288,6 +295,7 @@ void LLModel::normalizeVolumeFaces()
// the positions to fit within the unit cube.
LLVector4a* pos = (LLVector4a*) face.mPositions;
LLVector4a* norm = (LLVector4a*) face.mNormals;
+ LLVector4a* t = (LLVector4a*)face.mTangents;
for (U32 j = 0; j < face.mNumVertices; ++j)
{
@@ -298,6 +306,14 @@ void LLModel::normalizeVolumeFaces()
norm[j].mul(inv_scale);
norm[j].normalize3();
}
+
+ if (t)
+ {
+ F32 w = t[j].getF32ptr()[3];
+ t[j].mul(inv_scale);
+ t[j].normalize3();
+ t[j].getF32ptr()[3] = w;
+ }
}
}
@@ -311,6 +327,12 @@ void LLModel::normalizeVolumeFaces()
mNormalizedScale.set(normalized_scale.getF32ptr());
mNormalizedTranslation.set(trans.getF32ptr());
mNormalizedTranslation *= -1.f;
+
+ // remember normalized scale so original dimensions can be recovered for mesh processing (i.e. tangent generation)
+ for (auto& face : mVolumeFaces)
+ {
+ face.mNormalizedScale = mNormalizedScale;
+ }
}
}
@@ -371,6 +393,8 @@ void LLModel::setVolumeFaceData(
U32 num_verts,
U32 num_indices)
{
+ llassert(num_indices % 3 == 0);
+
LLVolumeFace& face = mVolumeFaces[f];
face.resizeVertices(num_verts);
@@ -718,10 +742,12 @@ LLSD LLModel::writeModel(
LLSD::Binary verts(face.mNumVertices*3*2);
LLSD::Binary tc(face.mNumVertices*2*2);
LLSD::Binary normals(face.mNumVertices*3*2);
+ LLSD::Binary tangents(face.mNumVertices * 4 * 2);
LLSD::Binary indices(face.mNumIndices*2);
U32 vert_idx = 0;
U32 norm_idx = 0;
+ //U32 tan_idx = 0;
U32 tc_idx = 0;
LLVector2* ftc = (LLVector2*) face.mTexCoords;
@@ -774,6 +800,24 @@ LLSD LLModel::writeModel(
normals[norm_idx++] = buff[1];
}
}
+
+#if 0 // keep this code for now in case we want to support transporting tangents with mesh assets
+ if (face.mTangents)
+ { //normals
+ F32* tangent = face.mTangents[j].getF32ptr();
+
+ for (U32 k = 0; k < 4; ++k)
+ { //for each component
+ //convert to 16-bit normalized
+ U16 val = (U16)((tangent[k] + 1.f) * 0.5f * 65535);
+ U8* buff = (U8*)&val;
+
+ //write to binary buffer
+ tangents[tan_idx++] = buff[0];
+ tangents[tan_idx++] = buff[1];
+ }
+ }
+#endif
//texcoord
if (face.mTexCoords)
@@ -804,6 +848,8 @@ LLSD LLModel::writeModel(
//write out face data
mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();
mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue();
+ mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue();
+
mdl[model_names[idx]][i]["Position"] = verts;
if (face.mNormals)
@@ -811,6 +857,13 @@ LLSD LLModel::writeModel(
mdl[model_names[idx]][i]["Normal"] = normals;
}
+#if 0 // keep this code for now in case we decide to transport tangents with mesh assets
+ if (face.mTangents)
+ {
+ mdl[model_names[idx]][i]["Tangent"] = tangents;
+ }
+#endif
+
if (face.mTexCoords)
{
mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue();
@@ -835,7 +888,7 @@ LLSD LLModel::writeModel(
{
LLVector3 pos(face.mPositions[j].getF32ptr());
- weight_list& weights = high->getJointInfluences(pos);
+ weight_list& weights = model[idx]->getJointInfluences(pos);
S32 count = 0;
for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
@@ -881,8 +934,6 @@ LLSD LLModel::writeModel(
LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm)
{
- U32 bytes = 0;
-
std::string::size_type cur_offset = 0;
LLSD header;
@@ -904,7 +955,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header["skin"]["offset"] = (LLSD::Integer) cur_offset;
header["skin"]["size"] = (LLSD::Integer) size;
cur_offset += size;
- bytes += size;
}
}
@@ -920,7 +970,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset;
header["physics_convex"]["size"] = (LLSD::Integer) size;
cur_offset += size;
- bytes += size;
}
}
@@ -942,7 +991,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset;
header[model_names[i]]["size"] = (LLSD::Integer) size;
cur_offset += size;
- bytes += size;
}
}
@@ -1545,6 +1593,25 @@ void LLMeshSkinInfo::updateHash()
mHash = digest[0];
}
+U32 LLMeshSkinInfo::sizeBytes() const
+{
+ U32 res = sizeof(LLUUID); // mMeshID
+
+ res += sizeof(std::vector<std::string>) + sizeof(std::string) * mJointNames.size();
+ for (U32 i = 0; i < mJointNames.size(); ++i)
+ {
+ res += mJointNames[i].size(); // actual size, not capacity
+ }
+
+ res += sizeof(std::vector<S32>) + sizeof(S32) * mJointNums.size();
+ res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mInvBindMatrix.size();
+ res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mAlternateBindMatrix.size();
+ res += 16 * sizeof(float); //mBindShapeMatrix
+ res += sizeof(float) + 3 * sizeof(bool);
+
+ return res;
+}
+
LLModel::Decomposition::Decomposition(LLSD& data)
{
fromLLSD(data);
@@ -1651,6 +1718,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
}
}
+U32 LLModel::Decomposition::sizeBytes() const
+{
+ U32 res = sizeof(LLUUID); // mMeshID
+
+ res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector<LLVector3>) * mHull.size();
+ for (U32 i = 0; i < mHull.size(); ++i)
+ {
+ res += mHull[i].size() * sizeof(LLVector3);
+ }
+
+ res += sizeof(LLModel::hull) + sizeof(LLVector3) * mBaseHull.size();
+
+ res += sizeof(std::vector<LLModel::PhysicsMesh>) + sizeof(std::vector<LLModel::PhysicsMesh>) * mMesh.size();
+ for (U32 i = 0; i < mMesh.size(); ++i)
+ {
+ res += mMesh[i].sizeBytes();
+ }
+
+ res += sizeof(std::vector<LLModel::PhysicsMesh>) * 2;
+ res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes();
+
+ return res;
+}
+
bool LLModel::Decomposition::hasHullList() const
{
return !mHull.empty() ;
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 3881b1338c..a6ab96ab18 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -50,6 +50,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
void updateHash();
+ U32 sizeBytes() const;
LLUUID mMeshID;
std::vector<std::string> mJointNames;
@@ -112,6 +113,14 @@ public:
{
return mPositions.empty();
}
+
+ U32 sizeBytes() const
+ {
+ U32 res = sizeof(std::vector<LLVector3>) * 2;
+ res += sizeof(LLVector3) * mPositions.size();
+ res += sizeof(LLVector3) * mNormals.size();
+ return res;
+ }
};
class Decomposition
@@ -122,6 +131,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD() const;
bool hasHullList() const;
+ U32 sizeBytes() const;
void merge(const Decomposition* rhs);
@@ -184,6 +194,7 @@ public:
void sortVolumeFacesByMaterialName();
void normalizeVolumeFaces();
void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
+ void remapVolumeFaces();
void optimizeVolumeFaces();
void offsetMesh( const LLVector3& pivotPoint );
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp
index 5171621007..554ed54de1 100644
--- a/indra/llprimitive/llmodelloader.cpp
+++ b/indra/llprimitive/llmodelloader.cpp
@@ -160,7 +160,8 @@ bool LLModelLoader::getSLMFilename(const std::string& model_filename, std::strin
std::string::size_type i = model_filename.rfind(".");
if (i != std::string::npos)
{
- slm_filename.replace(i, model_filename.size()-1, ".slm");
+ slm_filename.resize(i, '\0');
+ slm_filename.append(".slm");
return true;
}
else
@@ -172,7 +173,7 @@ bool LLModelLoader::getSLMFilename(const std::string& model_filename, std::strin
bool LLModelLoader::doLoadModel()
{
//first, look for a .slm file of the same name that was modified later
- //than the .dae
+ //than the specified model file
if (mTrySLM)
{
@@ -182,13 +183,13 @@ bool LLModelLoader::doLoadModel()
llstat slm_status;
if (LLFile::stat(slm_filename, &slm_status) == 0)
{ //slm file exists
- llstat dae_status;
- if (LLFile::stat(mFilename, &dae_status) != 0 ||
- dae_status.st_mtime < slm_status.st_mtime)
+ llstat model_file_status;
+ if (LLFile::stat(mFilename, &model_file_status) != 0 ||
+ model_file_status.st_mtime < slm_status.st_mtime)
{
if (loadFromSLM(slm_filename))
{ //slm successfully loaded, if this fails, fall through and
- //try loading from dae
+ //try loading from model file
mLod = -1; //successfully loading from an slm implicitly sets all
//LoDs
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 67c225d25d..8b470d235c 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -39,6 +39,7 @@
#include "llsdutil_math.h"
#include "llprimtexturelist.h"
#include "llmaterialid.h"
+#include "llsdutil.h"
/**
* exported constants
@@ -80,6 +81,14 @@ const F32 LIGHT_MIN_CUTOFF = 0.0f;
const F32 LIGHT_DEFAULT_CUTOFF = 0.0f;
const F32 LIGHT_MAX_CUTOFF = 180.f;
+// reflection probes
+const F32 REFLECTION_PROBE_MIN_AMBIANCE = 0.f;
+const F32 REFLECTION_PROBE_MAX_AMBIANCE = 1.f;
+const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE = 0.f;
+const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE = 0.f;
+const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE = 1024.f;
+const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE = 0.f;
+
// "Tension" => [0,10], increments of 0.1
const F32 FLEXIBLE_OBJECT_MIN_TENSION = 0.0f;
const F32 FLEXIBLE_OBJECT_DEFAULT_TENSION = 1.0f;
@@ -1690,6 +1699,10 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
return (size == 28);
case PARAMS_EXTENDED_MESH:
return (size == 4);
+ case PARAMS_RENDER_MATERIAL:
+ return (size > 1);
+ case PARAMS_REFLECTION_PROBE:
+ return (size == 9);
}
return FALSE;
@@ -1808,6 +1821,118 @@ bool LLLightParams::fromLLSD(LLSD& sd)
//============================================================================
+//============================================================================
+
+LLReflectionProbeParams::LLReflectionProbeParams()
+{
+ mType = PARAMS_REFLECTION_PROBE;
+}
+
+BOOL LLReflectionProbeParams::pack(LLDataPacker &dp) const
+{
+ dp.packF32(mAmbiance, "ambiance");
+ dp.packF32(mClipDistance, "clip_distance");
+ dp.packU8(mFlags, "flags");
+ return TRUE;
+}
+
+BOOL LLReflectionProbeParams::unpack(LLDataPacker &dp)
+{
+ F32 ambiance;
+ F32 clip_distance;
+
+ dp.unpackF32(ambiance, "ambiance");
+ setAmbiance(ambiance);
+
+ dp.unpackF32(clip_distance, "clip_distance");
+ setClipDistance(clip_distance);
+
+ dp.unpackU8(mFlags, "flags");
+
+ return TRUE;
+}
+
+bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const
+{
+ if (data.mType != PARAMS_REFLECTION_PROBE)
+ {
+ return false;
+ }
+ const LLReflectionProbeParams *param = (const LLReflectionProbeParams*)&data;
+ if (param->mAmbiance != mAmbiance)
+ {
+ return false;
+ }
+ if (param->mClipDistance != mClipDistance)
+ {
+ return false;
+ }
+ if (param->mFlags != mFlags)
+ {
+ return false;
+ }
+ return true;
+}
+
+void LLReflectionProbeParams::copy(const LLNetworkData& data)
+{
+ const LLReflectionProbeParams *param = (LLReflectionProbeParams*)&data;
+ mType = param->mType;
+ mAmbiance = param->mAmbiance;
+ mClipDistance = param->mClipDistance;
+ mFlags = param->mFlags;
+}
+
+LLSD LLReflectionProbeParams::asLLSD() const
+{
+ LLSD sd;
+ sd["ambiance"] = getAmbiance();
+ sd["clip_distance"] = getClipDistance();
+ sd["flags"] = mFlags;
+ return sd;
+}
+
+bool LLReflectionProbeParams::fromLLSD(LLSD& sd)
+{
+ if (!sd.has("ambiance") ||
+ !sd.has("clip_distance") ||
+ !sd.has("flags"))
+ {
+ return false;
+ }
+
+ setAmbiance((F32)sd["ambiance"].asReal());
+ setClipDistance((F32)sd["clip_distance"].asReal());
+ mFlags = (U8) sd["flags"].asInteger();
+
+ return true;
+}
+
+void LLReflectionProbeParams::setIsBox(bool is_box)
+{
+ if (is_box)
+ {
+ mFlags |= FLAG_BOX_VOLUME;
+ }
+ else
+ {
+ mFlags &= ~FLAG_BOX_VOLUME;
+ }
+}
+
+void LLReflectionProbeParams::setIsDynamic(bool is_dynamic)
+{
+ if (is_dynamic)
+ {
+ mFlags |= FLAG_DYNAMIC;
+ }
+ else
+ {
+ mFlags &= ~FLAG_DYNAMIC;
+ }
+}
+
+//============================================================================
LLFlexibleObjectData::LLFlexibleObjectData()
{
mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS;
@@ -2181,3 +2306,142 @@ bool LLExtendedMeshParams::fromLLSD(LLSD& sd)
return false;
}
+
+//============================================================================
+
+LLRenderMaterialParams::LLRenderMaterialParams()
+{
+ mType = PARAMS_RENDER_MATERIAL;
+}
+
+BOOL LLRenderMaterialParams::pack(LLDataPacker& dp) const
+{
+ U8 count = (U8)llmin((S32)mEntries.size(), 14); //limited to 255 bytes, no more than 14 material ids
+
+ dp.packU8(count, "count");
+ for (auto& entry : mEntries)
+ {
+ dp.packU8(entry.te_idx, "te_idx");
+ dp.packUUID(entry.id, "id");
+ }
+
+ return TRUE;
+}
+
+BOOL LLRenderMaterialParams::unpack(LLDataPacker& dp)
+{
+ U8 count;
+ dp.unpackU8(count, "count");
+ mEntries.resize(count);
+ for (auto& entry : mEntries)
+ {
+ dp.unpackU8(entry.te_idx, "te_idx");
+ dp.unpackUUID(entry.id, "te_id");
+ }
+
+ return TRUE;
+}
+
+bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const
+{
+ if (data.mType != PARAMS_RENDER_MATERIAL)
+ {
+ return false;
+ }
+
+ const LLRenderMaterialParams& param = static_cast<const LLRenderMaterialParams&>(data);
+
+ if (param.mEntries.size() != mEntries.size())
+ {
+ return false;
+ }
+
+ for (auto& entry : mEntries)
+ {
+ if (param.getMaterial(entry.te_idx) != entry.id)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void LLRenderMaterialParams::copy(const LLNetworkData& data)
+{
+ llassert_always(data.mType == PARAMS_RENDER_MATERIAL);
+ const LLRenderMaterialParams& param = static_cast<const LLRenderMaterialParams&>(data);
+ mEntries = param.mEntries;
+}
+
+LLSD LLRenderMaterialParams::asLLSD() const
+{
+ LLSD ret;
+
+ for (int i = 0; i < mEntries.size(); ++i)
+ {
+ ret[i]["te_idx"] = mEntries[i].te_idx;
+ ret[i]["id"] = mEntries[i].id;
+ }
+
+ return ret;
+}
+
+bool LLRenderMaterialParams::fromLLSD(LLSD& sd)
+{
+ if (sd.isArray())
+ {
+ mEntries.resize(sd.size());
+ for (int i = 0; i < sd.size(); ++i)
+ {
+ if (sd[i].has("te_idx") && sd.has("id"))
+ {
+ mEntries[i].te_idx = sd[i]["te_idx"].asInteger();
+ mEntries[i].id = sd[i]["id"].asUUID();
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id)
+{
+ for (int i = 0; i < mEntries.size(); ++i)
+ {
+ if (mEntries[i].te_idx == te)
+ {
+ if (id.isNull())
+ {
+ mEntries.erase(mEntries.begin() + i);
+ }
+ else
+ {
+ mEntries[i].id = id;
+ }
+ return;
+ }
+ }
+
+ mEntries.push_back({ te, id });
+}
+
+const LLUUID& LLRenderMaterialParams::getMaterial(U8 te) const
+{
+ for (int i = 0; i < mEntries.size(); ++i)
+ {
+ if (mEntries[i].te_idx == te)
+ {
+ return mEntries[i].id;
+ }
+ }
+
+ return LLUUID::null;
+}
+
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 309b18faa9..d2adfa4a3d 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -107,6 +107,8 @@ public:
PARAMS_RESERVED = 0x50, // Used on server-side
PARAMS_MESH = 0x60,
PARAMS_EXTENDED_MESH = 0x70,
+ PARAMS_RENDER_MATERIAL = 0x80,
+ PARAMS_REFLECTION_PROBE = 0x90,
};
public:
@@ -170,6 +172,50 @@ public:
F32 getCutoff() const { return mCutoff; }
};
+extern const F32 REFLECTION_PROBE_MIN_AMBIANCE;
+extern const F32 REFLECTION_PROBE_MAX_AMBIANCE;
+extern const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE;
+extern const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE;
+extern const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE;
+extern const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE;
+
+class LLReflectionProbeParams : public LLNetworkData
+{
+public:
+ enum EFlags : U8
+ {
+ FLAG_BOX_VOLUME = 0x01, // use a box influence volume
+ FLAG_DYNAMIC = 0x02, // render dynamic objects (avatars) into this Reflection Probe
+ };
+
+protected:
+ F32 mAmbiance = REFLECTION_PROBE_DEFAULT_AMBIANCE;
+ F32 mClipDistance = REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE;
+ U8 mFlags = 0;
+
+public:
+ LLReflectionProbeParams();
+ /*virtual*/ BOOL pack(LLDataPacker& dp) const;
+ /*virtual*/ BOOL unpack(LLDataPacker& dp);
+ /*virtual*/ bool operator==(const LLNetworkData& data) const;
+ /*virtual*/ void copy(const LLNetworkData& data);
+ // LLSD implementations here are provided by Eddy Stryker.
+ // NOTE: there are currently unused in protocols
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ void setAmbiance(F32 ambiance) { mAmbiance = llclamp(ambiance, REFLECTION_PROBE_MIN_AMBIANCE, REFLECTION_PROBE_MAX_AMBIANCE); }
+ void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); }
+ void setIsBox(bool is_box);
+ void setIsDynamic(bool is_dynamic);
+
+ F32 getAmbiance() const { return mAmbiance; }
+ F32 getClipDistance() const { return mClipDistance; }
+ bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; }
+ bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; }
+};
+
//-------------------------------------------------
// This structure is also used in the part of the
// code that creates new flexible objects.
@@ -320,6 +366,33 @@ public:
};
+class LLRenderMaterialParams : public LLNetworkData
+{
+private:
+ struct Entry
+ {
+ U8 te_idx;
+ LLUUID id;
+ };
+ std::vector< Entry > mEntries;
+
+public:
+ LLRenderMaterialParams();
+ BOOL pack(LLDataPacker& dp) const override;
+ BOOL unpack(LLDataPacker& dp) override;
+ bool operator==(const LLNetworkData& data) const override;
+ void copy(const LLNetworkData& data) override;
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ void setMaterial(U8 te_idx, const LLUUID& id);
+ const LLUUID& getMaterial(U8 te_idx) const;
+
+ bool isEmpty() { return mEntries.empty(); }
+};
+
+
// This code is not naming-standards compliant. Leaving it like this for
// now to make the connection to code in
// BOOL packTEMessage(LLDataPacker &dp) const;
@@ -415,12 +488,12 @@ public:
virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
virtual S32 setTEGlow(const U8 te, const F32 glow);
virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
- virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
+ virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
virtual void setTESelected(const U8 te, bool sel);
LLMaterialPtr getTEMaterialParams(const U8 index);
-
+
void copyTEs(const LLPrimitive *primitive);
S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
BOOL packTEMessage(LLMessageSystem *mesgsys) const;
@@ -498,6 +571,8 @@ public:
static LLPCode legacyToPCode(const U8 legacy);
static U8 pCodeToLegacy(const LLPCode pcode);
static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis);
+
+ BOOL hasRenderMaterialParams() const;
inline static BOOL isPrimitive(const LLPCode pcode);
inline static BOOL isApp(const LLPCode pcode);
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 284dfc15f4..d810c6ed25 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -80,22 +80,7 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
, mSelected(false)
, mMaterialUpdatePending(false)
{
- mID = rhs.mID;
- mScaleS = rhs.mScaleS;
- mScaleT = rhs.mScaleT;
- mOffsetS = rhs.mOffsetS;
- mOffsetT = rhs.mOffsetT;
- mRotation = rhs.mRotation;
- mColor = rhs.mColor;
- mBump = rhs.mBump;
- mMediaFlags = rhs.mMediaFlags;
- mGlow = rhs.mGlow;
- mMaterialID = rhs.mMaterialID;
- mMaterial = rhs.mMaterial;
- if (rhs.mMediaEntry != NULL) {
- // Make a copy
- mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
- }
+ *this = rhs;
}
LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
@@ -124,6 +109,17 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
else {
mMediaEntry = NULL;
}
+
+ mMaterialID = rhs.mMaterialID;
+
+ if (rhs.mGLTFMaterialOverrides.notNull())
+ {
+ mGLTFMaterialOverrides = new LLGLTFMaterial(*rhs.mGLTFMaterialOverrides);
+ }
+ else
+ {
+ mGLTFMaterialOverrides = nullptr;
+ }
}
return *this;
@@ -218,6 +214,11 @@ void LLTextureEntry::asLLSD(LLSD& sd) const
sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
}
sd["glow"] = mGlow;
+
+ if (mGLTFMaterialOverrides.notNull())
+ {
+ sd["gltf_override"] = mGLTFMaterialOverrides->asJSON();
+ }
}
bool LLTextureEntry::fromLLSD(const LLSD& sd)
@@ -282,6 +283,24 @@ bool LLTextureEntry::fromLLSD(const LLSD& sd)
setGlow((F32)sd[w].asReal() );
}
+ w = "gltf_override";
+ if (sd.has(w))
+ {
+ if (mGLTFMaterialOverrides.isNull())
+ {
+ mGLTFMaterialOverrides = new LLGLTFMaterial();
+ }
+
+ std::string warn_msg, error_msg;
+ if (!mGLTFMaterialOverrides->fromJSON(sd[w].asString(), warn_msg, error_msg))
+ {
+ LL_WARNS() << llformat("Failed to parse GLTF json: %s -- %s", warn_msg.c_str(), error_msg.c_str()) << LL_ENDL;
+ LL_WARNS() << sd[w].asString() << LL_ENDL;
+
+ mGLTFMaterialOverrides = nullptr;
+ }
+ }
+
return true;
fail:
return false;
@@ -491,6 +510,36 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny)
return TEM_CHANGE_NONE;
}
+void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material)
+{
+ mGLTFMaterial = material;
+ if (mGLTFMaterial == nullptr)
+ {
+ setGLTFRenderMaterial(nullptr);
+ }
+}
+
+LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
+{
+ if (mGLTFRenderMaterial.notNull())
+ {
+ return mGLTFRenderMaterial;
+ }
+
+ llassert(getGLTFMaterialOverride() == nullptr);
+ return getGLTFMaterial();
+}
+
+S32 LLTextureEntry::setGLTFRenderMaterial(LLGLTFMaterial* mat)
+{
+ if (mGLTFRenderMaterial != mat)
+ {
+ mGLTFRenderMaterial = mat;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
+}
+
S32 LLTextureEntry::setMediaFlags(U8 media_flags)
{
media_flags &= TEM_MEDIA_MASK;
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index dc2e201044..e37bc9a3b6 100644
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -32,6 +32,7 @@
#include "llsd.h"
#include "llmaterialid.h"
#include "llmaterial.h"
+#include "llgltfmaterial.h"
// These bits are used while unpacking TEM messages to tell which aspects of
// the texture entry changed.
@@ -193,6 +194,19 @@ public:
// Media flags
enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
+ // GLTF asset
+ void setGLTFMaterial(LLGLTFMaterial* material);
+ LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; }
+
+ // GLTF override
+ LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; }
+ void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; }
+
+ // GLTF render material
+ // nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter
+ LLGLTFMaterial* getGLTFRenderMaterial() const;
+ S32 setGLTFRenderMaterial(LLGLTFMaterial* mat);
+
public:
F32 mScaleS; // S, T offset
F32 mScaleT; // S, T offset
@@ -219,6 +233,17 @@ protected:
bool mMaterialUpdatePending;
LLMaterialID mMaterialID;
LLMaterialPtr mMaterial;
+
+ // Reference to GLTF material asset state
+ // On the viewer, this should be the same LLGLTFMaterial instance that exists in LLGLTFMaterialList
+ LLPointer<LLGLTFMaterial> mGLTFMaterial;
+
+ // GLTF material parameter overrides -- the viewer will use this data to override material parameters
+ // set by the asset and store the results in mRenderGLTFMaterial
+ LLPointer<LLGLTFMaterial> mGLTFMaterialOverrides;
+
+ // GLTF material to use for rendering -- will always be an LLFetchedGLTFMaterial
+ LLPointer<LLGLTFMaterial> mGLTFRenderMaterial;
// Note the media data is not sent via the same message structure as the rest of the TE
LLMediaEntry* mMediaEntry; // The media data for the face
diff --git a/indra/llprimitive/tests/llmessagesystem_stub.cpp b/indra/llprimitive/tests/llmessagesystem_stub.cpp
index 04e70945c4..9006833054 100644
--- a/indra/llprimitive/tests/llmessagesystem_stub.cpp
+++ b/indra/llprimitive/tests/llmessagesystem_stub.cpp
@@ -25,7 +25,7 @@
#include "linden_common.h"
-char * _PREHASH_TextureEntry;
+const char * const _PREHASH_TextureEntry = "TextureEntry";
S32 LLMessageSystem::getSizeFast(char const*, char const*) const
{
diff --git a/indra/llprimitive/tests/llprimitive_test.cpp b/indra/llprimitive/tests/llprimitive_test.cpp
index 0d60c7cd15..0ff0795fdc 100644
--- a/indra/llprimitive/tests/llprimitive_test.cpp
+++ b/indra/llprimitive/tests/llprimitive_test.cpp
@@ -71,6 +71,46 @@ private:
S32 mCurrDetailTest;
};
+LLMaterialID::LLMaterialID() {}
+LLMaterialID::LLMaterialID(LLMaterialID const &m) = default;
+LLMaterialID::~LLMaterialID() {}
+void LLMaterialID::set(void const*) { }
+U8 const * LLMaterialID::get() const { return mID; }
+
+LLPrimTextureList::LLPrimTextureList() { }
+LLPrimTextureList::~LLPrimTextureList() { }
+S32 LLPrimTextureList::setBumpMap(const U8 index, const U8 bump) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setOffsetS(const U8 index, const F32 s) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setOffsetT(const U8 index, const F32 t) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry &te) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setRotation(const U8 index, const F32 r) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setBumpShiny(const U8 index, const U8 bump_shiny) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setFullbright(const U8 index, const U8 t) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setMediaTexGen(const U8 index, const U8 media) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setBumpShinyFullbright(const U8 index, const U8 bump) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setID(const U8 index, const LLUUID& id) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setAlpha(const U8 index, const F32 alpha) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setColor(const U8 index, const LLColor3& color) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setColor(const U8 index, const LLColor4& color) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setScale(const U8 index, const F32 s, const F32 t) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setScaleS(const U8 index, const F32 s) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setScaleT(const U8 index, const F32 t) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setShiny(const U8 index, const U8 shiny) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setOffset(const U8 index, const F32 s, const F32 t) { return TEM_CHANGE_NONE; }
+S32 LLPrimTextureList::setTexGen(const U8 index, const U8 texgen) { return TEM_CHANGE_NONE; }
+
+LLMaterialPtr LLPrimTextureList::getMaterialParams(const U8 index) { return LLMaterialPtr(); }
+void LLPrimTextureList::copy(LLPrimTextureList const & ptl) { mEntryList = ptl.mEntryList; } // do we need to call getTexture()->newCopy()?
+void LLPrimTextureList::take(LLPrimTextureList &other_list) { }
+void LLPrimTextureList::setSize(S32 new_size) { mEntryList.resize(new_size); }
+void LLPrimTextureList::setAllIDs(const LLUUID &id) { }
+LLTextureEntry * LLPrimTextureList::getTexture(const U8 index) const { return nullptr; }
+S32 LLPrimTextureList::size() const { return mEntryList.size(); }
+
class PRIMITIVE_TEST_SETUP
{
public:
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index baab09a104..a30f47f1d9 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -31,6 +31,7 @@ include_directories(SYSTEM
set(llrender_SOURCE_FILES
llatmosphere.cpp
llcubemap.cpp
+ llcubemaparray.cpp
llfontbitmapcache.cpp
llfontfreetype.cpp
llfontgl.cpp
@@ -58,6 +59,7 @@ set(llrender_HEADER_FILES
llatmosphere.h
llcubemap.h
+ llcubemaparray.h
llfontgl.h
llfontfreetype.h
llfontbitmapcache.h
diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp
index ffc17c89f8..8e37ca9b90 100644
--- a/indra/llrender/llatmosphere.cpp
+++ b/indra/llrender/llatmosphere.cpp
@@ -241,7 +241,7 @@ LLGLTexture* LLAtmosphere::getTransmittance()
m_transmittance->generateGLTexture();
m_transmittance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
m_transmittance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
- m_transmittance->setExplicitFormat(GL_RGB32F_ARB, GL_RGB, GL_FLOAT);
+ m_transmittance->setExplicitFormat(GL_RGB32F, GL_RGB, GL_FLOAT);
m_transmittance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE);
}
return m_transmittance;
@@ -255,7 +255,7 @@ LLGLTexture* LLAtmosphere::getScattering()
m_scattering->generateGLTexture();
m_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
m_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
- m_scattering->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT);
+ m_scattering->setExplicitFormat(GL_RGB16F, GL_RGB, GL_FLOAT);
m_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D);
}
return m_scattering;
@@ -269,7 +269,7 @@ LLGLTexture* LLAtmosphere::getMieScattering()
m_mie_scatter_texture->generateGLTexture();
m_mie_scatter_texture->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
m_mie_scatter_texture->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
- m_mie_scatter_texture->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT);
+ m_mie_scatter_texture->setExplicitFormat(GL_RGB16F, GL_RGB, GL_FLOAT);
m_mie_scatter_texture->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D);
}
return m_mie_scatter_texture;
@@ -283,7 +283,7 @@ LLGLTexture* LLAtmosphere::getIlluminance()
m_illuminance->generateGLTexture();
m_illuminance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
m_illuminance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
- m_illuminance->setExplicitFormat(GL_RGB32F_ARB, GL_RGB, GL_FLOAT);
+ m_illuminance->setExplicitFormat(GL_RGB32F, GL_RGB, GL_FLOAT);
m_illuminance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE);
}
return m_illuminance;
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 834084674e..254288a86e 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -40,8 +40,9 @@
#include "llglheaders.h"
-const F32 epsilon = 1e-7f;
-const U16 RESOLUTION = 64;
+namespace {
+ const U16 RESOLUTION = 64;
+}
bool LLCubeMap::sUseCubeMaps = true;
@@ -50,12 +51,12 @@ LLCubeMap::LLCubeMap(bool init_as_srgb)
mMatrixStage(0),
mIssRGB(init_as_srgb)
{
- mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
- mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
- mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
- mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
- mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
- mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
+ mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
+ mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
+ mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
+ mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+ mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
}
LLCubeMap::~LLCubeMap()
@@ -66,7 +67,7 @@ void LLCubeMap::initGL()
{
llassert(gGLManager.mInited);
- if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+ if (LLCubeMap::sUseCubeMaps)
{
// Not initialized, do stuff.
if (mImages[0].isNull())
@@ -166,6 +167,73 @@ void LLCubeMap::init(const std::vector<LLPointer<LLImageRaw> >& rawimages)
}
}
+void LLCubeMap::initReflectionMap(U32 resolution, U32 components)
+{
+ U32 texname = 0;
+
+ LLImageGL::generateTextures(1, &texname);
+
+ mImages[0] = new LLImageGL(resolution, resolution, components, TRUE);
+ mImages[0]->setTexName(texname);
+ mImages[0]->setTarget(mTargets[0], LLTexUnit::TT_CUBE_MAP);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
+ mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+}
+
+void LLCubeMap::initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& rawimages)
+{
+ llassert(rawimages.size() == 6);
+
+ U32 texname = 0;
+
+ LLImageGL::generateTextures(1, &texname);
+
+ U32 resolution = rawimages[0]->getWidth();
+ U32 components = rawimages[0]->getComponents();
+
+ for (int i = 0; i < 6; i++)
+ {
+ llassert(rawimages[i]->getWidth() == resolution);
+ llassert(rawimages[i]->getHeight() == resolution);
+ llassert(rawimages[i]->getComponents() == components);
+
+ mImages[i] = new LLImageGL(resolution, resolution, components, TRUE);
+ mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
+ mRawImages[i] = rawimages[i];
+ mImages[i]->createGLTexture(0, mRawImages[i], texname);
+
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
+ mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ stop_glerror();
+
+ mImages[i]->setSubImage(mRawImages[i], 0, 0, resolution, resolution);
+ }
+ enableTexture(0);
+ bind();
+ mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+ gGL.getTexUnit(0)->disable();
+ disable();
+}
+
+void LLCubeMap::generateMipMaps()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+
+ mImages[0]->setUseMipMaps(TRUE);
+ mImages[0]->setHasMipMaps(TRUE);
+ enableTexture(0);
+ bind();
+ mImages[0]->setFilteringOption(LLTexUnit::TFO_BILINEAR);
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cmgmm - glGenerateMipmap");
+ glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+ }
+ gGL.getTexUnit(0)->disable();
+ disable();
+}
+
GLuint LLCubeMap::getGLName()
{
return mImages[0]->getTexName();
@@ -184,7 +252,7 @@ void LLCubeMap::enable(S32 stage)
void LLCubeMap::enableTexture(S32 stage)
{
mTextureStage = stage;
- if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
+ if (stage >= 0 && LLCubeMap::sUseCubeMaps)
{
gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP);
}
@@ -197,7 +265,7 @@ void LLCubeMap::disable(void)
void LLCubeMap::disableTexture(void)
{
- if (gGLManager.mHasCubeMap && mTextureStage >= 0 && LLCubeMap::sUseCubeMaps)
+ if (mTextureStage >= 0 && LLCubeMap::sUseCubeMaps)
{
gGL.getTexUnit(mTextureStage)->disable();
if (mTextureStage == 0)
@@ -256,191 +324,6 @@ void LLCubeMap::restoreMatrix()
}*/
}
-void LLCubeMap::setReflection (void)
-{
- gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getGLName());
- mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
-}
-
-LLVector3 LLCubeMap::map(U8 side, U16 v_val, U16 h_val) const
-{
- LLVector3 dir;
-
- const U8 curr_coef = side >> 1; // 0/1 = X axis, 2/3 = Y, 4/5 = Z
- const S8 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1
- const U8 i_coef = (curr_coef + 1) % 3;
- const U8 j_coef = (i_coef + 1) % 3;
-
- dir.mV[curr_coef] = side_dir;
-
- switch (side)
- {
- case 0: // negative X
- dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1;
- dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1;
- break;
- case 1: // positive X
- dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1;
- dir.mV[j_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1;
- break;
- case 2: // negative Y
- dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1;
- dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1;
- break;
- case 3: // positive Y
- dir.mV[i_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1;
- dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1;
- break;
- case 4: // negative Z
- dir.mV[i_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1;
- dir.mV[j_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1;
- break;
- case 5: // positive Z
- dir.mV[i_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1;
- dir.mV[j_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1;
- break;
- default:
- dir.mV[i_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1;
- dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1;
- }
-
- dir.normVec();
- return dir;
-}
-
-
-BOOL LLCubeMap::project(F32& v_val, F32& h_val, BOOL& outside,
- U8 side, const LLVector3& dir) const
-{
- const U8 curr_coef = side >> 1; // 0/1 = X axis, 2/3 = Y, 4/5 = Z
- const S8 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1
- const U8 i_coef = (curr_coef + 1) % 3;
- const U8 j_coef = (i_coef + 1) % 3;
-
- outside = TRUE;
- if (side_dir * dir.mV[curr_coef] < 0)
- return FALSE;
-
- LLVector3 ray;
-
- F32 norm_val = fabs(dir.mV[curr_coef]);
-
- if (norm_val < epsilon)
- norm_val = 1e-5f;
-
- ray.mV[curr_coef] = side_dir;
- ray.mV[i_coef] = dir.mV[i_coef] / norm_val;
- ray.mV[j_coef] = dir.mV[j_coef] / norm_val;
-
-
- const F32 i_val = (ray.mV[i_coef] + 1) * 0.5f * RESOLUTION;
- const F32 j_val = (ray.mV[j_coef] + 1) * 0.5f * RESOLUTION;
-
- switch (side)
- {
- case 0: // negative X
- v_val = RESOLUTION - i_val;
- h_val = j_val;
- break;
- case 1: // positive X
- v_val = RESOLUTION - i_val;
- h_val = RESOLUTION - j_val;
- break;
- case 2: // negative Y
- v_val = RESOLUTION - i_val;
- h_val = j_val;
- break;
- case 3: // positive Y
- v_val = i_val;
- h_val = j_val;
- break;
- case 4: // negative Z
- v_val = RESOLUTION - j_val;
- h_val = RESOLUTION - i_val;
- break;
- case 5: // positive Z
- v_val = RESOLUTION - j_val;
- h_val = i_val;
- break;
- default:
- v_val = i_val;
- h_val = j_val;
- }
-
- outside = ((v_val < 0) || (v_val > RESOLUTION) ||
- (h_val < 0) || (h_val > RESOLUTION));
-
- return TRUE;
-}
-
-BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max,
- U8 side, LLVector3 dir[4]) const
-{
- v_min = h_min = RESOLUTION;
- v_max = h_max = 0;
-
- BOOL fully_outside = TRUE;
- for (U8 vtx = 0; vtx < 4; ++vtx)
- {
- F32 v_val, h_val;
- BOOL outside;
- BOOL consider = project(v_val, h_val, outside, side, dir[vtx]);
- if (!outside)
- fully_outside = FALSE;
- if (consider)
- {
- if (v_val < v_min) v_min = v_val;
- if (v_val > v_max) v_max = v_val;
- if (h_val < h_min) h_min = h_val;
- if (h_val > h_max) h_max = h_val;
- }
- }
-
- v_min = llmax(0.0f, v_min);
- v_max = llmin(RESOLUTION - epsilon, v_max);
- h_min = llmax(0.0f, h_min);
- h_max = llmin(RESOLUTION - epsilon, h_max);
-
- return !fully_outside;
-}
-
-
-void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col)
-{
- LL_PROFILE_ZONE_SCOPED;
- F32 v_min, v_max, h_min, h_max;
- LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3];
- center.normVec();
-
- for (U8 side = 0; side < 6; ++side)
- {
- if (!project(v_min, v_max, h_min, h_max, side, dir))
- continue;
-
- U8 *td = mRawImages[side]->getData();
-
- U16 v_minu = (U16) v_min;
- U16 v_maxu = (U16) (ceil(v_max) + 0.5);
- U16 h_minu = (U16) h_min;
- U16 h_maxu = (U16) (ceil(h_max) + 0.5);
-
- for (U16 v = v_minu; v < v_maxu; ++v)
- for (U16 h = h_minu; h < h_maxu; ++h)
- //for (U16 v = 0; v < RESOLUTION; ++v)
- // for (U16 h = 0; h < RESOLUTION; ++h)
- {
- const LLVector3 ray = map(side, v, h);
- if (ray * center > 0.999)
- {
- const U32 offset = (RESOLUTION * v + h) * 4;
- for (U8 cc = 0; cc < 3; ++cc)
- td[offset + cc] = U8((td[offset + cc] + col.mV[cc]) * 0.5);
- }
- }
- mImages[side]->setSubImage(mRawImages[side], 0, 0, RESOLUTION, RESOLUTION);
- }
-}
void LLCubeMap::destroyGL()
{
diff --git a/indra/llrender/llcubemap.h b/indra/llrender/llcubemap.h
index a01636d8d4..b9e081cea3 100644
--- a/indra/llrender/llcubemap.h
+++ b/indra/llrender/llcubemap.h
@@ -40,6 +40,17 @@ class LLCubeMap : public LLRefCount
public:
LLCubeMap(bool init_as_srgb);
void init(const std::vector<LLPointer<LLImageRaw> >& rawimages);
+
+ // initialize as an undefined cubemap at the given resolution
+ // used for render-to-cubemap operations
+ // avoids usage of LLImageRaw
+ void initReflectionMap(U32 resolution, U32 components = 3);
+
+ // init from environment map images
+ // Similar to init, but takes ownership of rawimages and makes this cubemap
+ // respect the resolution of rawimages
+ // Raw images must point to array of six square images that are all the same resolution
+ void initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& rawimages);
void initGL();
void initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages);
void initGLData();
@@ -54,18 +65,15 @@ public:
void disableTexture(void);
void setMatrix(S32 stage);
void restoreMatrix();
- void setReflection (void);
- void finishPaint();
+ U32 getResolution() { return mImages[0].notNull() ? mImages[0]->getWidth(0) : 0; }
+
+ // generate mip maps for this Cube Map using GL
+ // NOTE: Cube Map MUST already be resident in VRAM
+ void generateMipMaps();
GLuint getGLName();
- LLVector3 map(U8 side, U16 v_val, U16 h_val) const;
- BOOL project(F32& v_val, F32& h_val, BOOL& outside,
- U8 side, const LLVector3& dir) const;
- BOOL project(F32& v_min, F32& v_max, F32& h_min, F32& h_max,
- U8 side, LLVector3 dir[4]) const;
- void paintIn(LLVector3 dir[4], const LLColor4U& col);
void destroyGL();
public:
diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
new file mode 100644
index 0000000000..a21f7d084e
--- /dev/null
+++ b/indra/llrender/llcubemaparray.cpp
@@ -0,0 +1,165 @@
+/**
+ * @file llcubemaparray.cpp
+ * @brief LLCubeMap class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+#include "llworkerthread.h"
+
+#include "llcubemaparray.h"
+
+#include "v4coloru.h"
+#include "v3math.h"
+#include "v3dmath.h"
+#include "m3math.h"
+#include "m4math.h"
+
+#include "llrender.h"
+#include "llglslshader.h"
+
+#include "llglheaders.h"
+
+//#pragma optimize("", off)
+
+// MUST match order of OpenGL face-layers
+GLenum LLCubeMapArray::sTargets[6] =
+{
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
+};
+
+LLVector3 LLCubeMapArray::sLookVecs[6] =
+{
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+ LLVector3(0, 1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1)
+};
+
+LLVector3 LLCubeMapArray::sUpVecs[6] =
+{
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1),
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0)
+};
+
+LLVector3 LLCubeMapArray::sClipToCubeLookVecs[6] =
+{
+ LLVector3(0, 0, -1), //GOOD
+ LLVector3(0, 0, 1), //GOOD
+
+ LLVector3(1, 0, 0), // GOOD
+ LLVector3(1, 0, 0), // GOOD
+
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+};
+
+LLVector3 LLCubeMapArray::sClipToCubeUpVecs[6] =
+{
+ LLVector3(-1, 0, 0), //GOOD
+ LLVector3(1, 0, 0), //GOOD
+
+ LLVector3(0, 1, 0), // GOOD
+ LLVector3(0, -1, 0), // GOOD
+
+ LLVector3(0, 0, -1),
+ LLVector3(0, 0, 1)
+};
+
+LLCubeMapArray::LLCubeMapArray()
+ : mTextureStage(0)
+{
+
+}
+
+LLCubeMapArray::~LLCubeMapArray()
+{
+}
+
+void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL use_mips)
+{
+ U32 texname = 0;
+
+ LLImageGL::generateTextures(1, &texname);
+
+ mImage = new LLImageGL(resolution, resolution, components, use_mips);
+ mImage->setTexName(texname);
+ mImage->setTarget(sTargets[0], LLTexUnit::TT_CUBE_MAP_ARRAY);
+
+ mImage->setUseMipMaps(use_mips);
+ mImage->setHasMipMaps(use_mips);
+
+ bind(0);
+
+ U32 format = components == 4 ? GL_RGBA12 : GL_RGB10;
+
+ glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, format, resolution, resolution, count*6, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, nullptr);
+
+ mImage->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+ if (use_mips)
+ {
+ mImage->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ glGenerateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY);
+ }
+ else
+ {
+ mImage->setFilteringOption(LLTexUnit::TFO_BILINEAR);
+ }
+
+ unbind();
+}
+
+void LLCubeMapArray::bind(S32 stage)
+{
+ mTextureStage = stage;
+ gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_CUBE_MAP_ARRAY, getGLName(), mImage->getUseMipMaps());
+}
+
+void LLCubeMapArray::unbind()
+{
+ gGL.getTexUnit(mTextureStage)->unbind(LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTextureStage = -1;
+}
+
+GLuint LLCubeMapArray::getGLName()
+{
+ return mImage->getTexName();
+}
+
+void LLCubeMapArray::destroyGL()
+{
+ mImage = NULL;
+}
diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h
new file mode 100644
index 0000000000..19c86278a1
--- /dev/null
+++ b/indra/llrender/llcubemaparray.h
@@ -0,0 +1,68 @@
+/**
+ * @file llcubemaparray.h
+ * @brief LLCubeMap class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#pragma once
+
+#include "llgl.h"
+
+#include <vector>
+
+class LLVector3;
+
+class LLCubeMapArray : public LLRefCount
+{
+public:
+ LLCubeMapArray();
+
+ static GLenum sTargets[6];
+
+ // look and up vectors for each cube face (agent space)
+ static LLVector3 sLookVecs[6];
+ static LLVector3 sUpVecs[6];
+
+ // look and up vectors for each cube face (clip space)
+ static LLVector3 sClipToCubeLookVecs[6];
+ static LLVector3 sClipToCubeUpVecs[6];
+
+ // allocate a cube map array
+ // res - resolution of each cube face
+ // components - number of components per pixel
+ // count - number of cube maps in the array
+ // use_mips - if TRUE, mipmaps will be allocated for this cube map array and anisotropic filtering will be used
+ void allocate(U32 res, U32 components, U32 count, BOOL use_mips = TRUE);
+ void bind(S32 stage);
+ void unbind();
+
+ GLuint getGLName();
+
+ void destroyGL();
+
+protected:
+ friend class LLTexUnit;
+ ~LLCubeMapArray();
+ LLPointer<LLImageGL> mImage;
+ S32 mTextureStage;
+};
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 18168d1c3f..e15157af05 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -60,11 +60,11 @@
BOOL gDebugSession = FALSE;
+BOOL gDebugGLSession = FALSE;
BOOL gClothRipple = FALSE;
BOOL gHeadlessClient = FALSE;
BOOL gNonInteractive = FALSE;
BOOL gGLActive = FALSE;
-BOOL gGLDebugLoggingEnabled = TRUE;
static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
static const std::string HEADLESS_RENDERER_STRING("Headless");
@@ -86,33 +86,38 @@ void APIENTRY gl_debug_callback(GLenum source,
const GLchar* message,
GLvoid* userParam)
{
- if (gGLDebugLoggingEnabled)
- {
-
- if (severity != GL_DEBUG_SEVERITY_HIGH_ARB &&
- severity != GL_DEBUG_SEVERITY_MEDIUM_ARB &&
- severity != GL_DEBUG_SEVERITY_LOW_ARB)
- { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints)
- return;
- }
-
- if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
- {
- LL_WARNS() << "----- GL ERROR --------" << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "----- GL WARNING -------" << LL_ENDL;
- }
- LL_WARNS() << "Type: " << std::hex << type << LL_ENDL;
- LL_WARNS() << "ID: " << std::hex << id << LL_ENDL;
- LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL;
- LL_WARNS() << "Message: " << message << LL_ENDL;
- LL_WARNS() << "-----------------------" << LL_ENDL;
- if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
- {
- LL_ERRS() << "Halting on GL Error" << LL_ENDL;
- }
+ if (severity != GL_DEBUG_SEVERITY_HIGH // &&
+ //severity != GL_DEBUG_SEVERITY_MEDIUM &&
+ //severity != GL_DEBUG_SEVERITY_LOW
+ )
+ { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints)
+ return;
+ }
+
+ if (severity == GL_DEBUG_SEVERITY_HIGH)
+ {
+ LL_WARNS() << "----- GL ERROR --------" << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "----- GL WARNING -------" << LL_ENDL;
+ }
+ LL_WARNS() << "Type: " << std::hex << type << LL_ENDL;
+ LL_WARNS() << "ID: " << std::hex << id << LL_ENDL;
+ LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL;
+ LL_WARNS() << "Message: " << message << LL_ENDL;
+ LL_WARNS() << "-----------------------" << LL_ENDL;
+
+ GLint vao = 0;
+ glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao);
+ GLint vbo = 0;
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vbo);
+ GLint ibo = 0;
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo);
+
+ if (severity == GL_DEBUG_SEVERITY_HIGH)
+ {
+ LL_ERRS() << "Halting on GL Error" << LL_ENDL;
}
}
#endif
@@ -163,246 +168,770 @@ std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
#if LL_WINDOWS
-PFNGLGETSTRINGIPROC glGetStringi = NULL;
-#endif
-
-// vertex blending prototypes
-PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB = NULL;
-PFNGLVERTEXBLENDARBPROC glVertexBlendARB = NULL;
-PFNGLWEIGHTFVARBPROC glWeightfvARB = NULL;
-
-// Vertex buffer object prototypes
-PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
-PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
-PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
-PFNGLISBUFFERARBPROC glIsBufferARB = NULL;
-PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
-PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB = NULL;
-PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB = NULL;
-PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL;
-PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
-PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL;
-PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
-
-//GL_ARB_vertex_array_object
-PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
-PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
-PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
-PFNGLISVERTEXARRAYPROC glIsVertexArray = NULL;
-
-// GL_ARB_map_buffer_range
-PFNGLMAPBUFFERRANGEPROC glMapBufferRange = NULL;
-PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange = NULL;
-
-// GL_ARB_sync
-PFNGLFENCESYNCPROC glFenceSync = NULL;
-PFNGLISSYNCPROC glIsSync = NULL;
-PFNGLDELETESYNCPROC glDeleteSync = NULL;
-PFNGLCLIENTWAITSYNCPROC glClientWaitSync = NULL;
-PFNGLWAITSYNCPROC glWaitSync = NULL;
-PFNGLGETINTEGER64VPROC glGetInteger64v = NULL;
-PFNGLGETSYNCIVPROC glGetSynciv = NULL;
-
-// GL_APPLE_flush_buffer_range
-PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE = NULL;
-PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE = NULL;
-
-// GL_ARB_occlusion_query
-PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;
-PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB = NULL;
-PFNGLISQUERYARBPROC glIsQueryARB = NULL;
-PFNGLBEGINQUERYARBPROC glBeginQueryARB = NULL;
-PFNGLENDQUERYARBPROC glEndQueryARB = NULL;
-PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
-PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
-PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
-
-// GL_ARB_timer_query
-PFNGLQUERYCOUNTERPROC glQueryCounter = NULL;
-PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v = NULL;
-PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
-
-// GL_ARB_point_parameters
-PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;
-PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL;
-
-// GL_ARB_framebuffer_object
-PFNGLISRENDERBUFFERPROC glIsRenderbuffer = NULL;
-PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = NULL;
-PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = NULL;
-PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = NULL;
-PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = NULL;
-PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv = NULL;
-PFNGLISFRAMEBUFFERPROC glIsFramebuffer = NULL;
-PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL;
-PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL;
-PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL;
-PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL;
-PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D = NULL;
-PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL;
-PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D = NULL;
-PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = NULL;
-PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv = NULL;
-PFNGLGENERATEMIPMAPPROC glGenerateMipmap = NULL;
-PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL;
-PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL;
-PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL;
-
-//GL_ARB_texture_multisample
-PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample = NULL;
-PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;
-PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;
-PFNGLSAMPLEMASKIPROC glSampleMaski = NULL;
-
-//transform feedback (4.0 core)
-PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL;
-PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL;
-PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL;
-PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL;
-PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL;
-
-//GL_ARB_debug_output
-PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
-PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
-PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB = NULL;
-PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = NULL;
-
-// GL_EXT_blend_func_separate
-PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
-
-// GL_ARB_draw_buffers
-PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL;
-
-//shader object prototypes
-PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
-PFNGLGETHANDLEARBPROC glGetHandleARB = NULL;
-PFNGLDETACHOBJECTARBPROC glDetachObjectARB = NULL;
-PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
-PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
-PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
-PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL;
-PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL;
-PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
-PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL;
-PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB = NULL;
-PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL;
-PFNGLUNIFORM2FARBPROC glUniform2fARB = NULL;
-PFNGLUNIFORM3FARBPROC glUniform3fARB = NULL;
-PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL;
-PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL;
-PFNGLUNIFORM2IARBPROC glUniform2iARB = NULL;
-PFNGLUNIFORM3IARBPROC glUniform3iARB = NULL;
-PFNGLUNIFORM4IARBPROC glUniform4iARB = NULL;
-PFNGLUNIFORM1FVARBPROC glUniform1fvARB = NULL;
-PFNGLUNIFORM2FVARBPROC glUniform2fvARB = NULL;
-PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL;
-PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL;
-PFNGLUNIFORM1IVARBPROC glUniform1ivARB = NULL;
-PFNGLUNIFORM2IVARBPROC glUniform2ivARB = NULL;
-PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL;
-PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL;
-PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB = NULL;
-PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL;
-PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv = NULL;
-PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB = NULL;
-PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB = NULL;
-PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
-PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
-PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB = NULL;
-PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
-PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
-PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
-PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
-PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
-PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;
+// WGL_ARB_create_context
+PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr;
+
+// WGL_AMD_gpu_association
+PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD = nullptr;
+PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD = nullptr;
+PFNWGLGETCONTEXTGPUIDAMDPROC wglGetContextGPUIDAMD = nullptr;
+PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC wglCreateAssociatedContextAMD = nullptr;
+PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC wglCreateAssociatedContextAttribsAMD = nullptr;
+PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC wglDeleteAssociatedContextAMD = nullptr;
+PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC wglMakeAssociatedContextCurrentAMD = nullptr;
+PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC wglGetCurrentAssociatedContextAMD = nullptr;
+PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC wglBlitContextFramebufferAMD = nullptr;
+
+// WGL_EXT_swap_control
+PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr;
+PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = nullptr;
-#if LL_WINDOWS
-PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
#endif
-// vertex shader prototypes
-#if LL_LINUX
-PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
-PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB = NULL;
-PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB = NULL;
-PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB = NULL;
-PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB = NULL;
-PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB = NULL;
-PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB = NULL;
-PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB = NULL;
-PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB = NULL;
-PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB = NULL;
-PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB = NULL;
-PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB = NULL;
-PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB = NULL;
-PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB = NULL;
-PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB = NULL;
-PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB = NULL;
-PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB = NULL;
-PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB = NULL;
-#endif // LL_LINUX
-PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB = NULL;
-PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB = NULL;
-PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB = NULL;
-PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB = NULL;
-PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB = NULL;
-PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB = NULL;
-PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB = NULL;
-#if LL_LINUX
-PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB = NULL;
-PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB = NULL;
-PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB = NULL;
-PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB = NULL;
-PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB = NULL;
-PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB = NULL;
-PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB = NULL;
-PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB = NULL;
-PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB = NULL;
-PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB = NULL;
-PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB = NULL;
-PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL;
-PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL;
-PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL;
-PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL;
-PFNGLBINDPROGRAMARBPROC glBindProgramARB = NULL;
-PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB = NULL;
-PFNGLGENPROGRAMSARBPROC glGenProgramsARB = NULL;
-PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB = NULL;
-PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB = NULL;
-PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB = NULL;
-PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB = NULL;
-PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB = NULL;
-PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB = NULL;
-PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB = NULL;
-PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB = NULL;
-PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB = NULL;
-PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB = NULL;
-PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB = NULL;
-PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB = NULL;
-PFNGLGETPROGRAMIVARBPROC glGetProgramivARB = NULL;
-PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB = NULL;
-PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB = NULL;
-PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB = NULL;
-PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB = NULL;
-PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB = NULL;
-PFNGLISPROGRAMARBPROC glIsProgramARB = NULL;
-#endif // LL_LINUX
-PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB = NULL;
-PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;
-PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
-
-#if LL_WINDOWS
-PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD = NULL;
-PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD = NULL;
-PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
-#endif
+// GL_VERSION_1_2
+//PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = nullptr;
+//PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr;
+//PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr;
+//PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D = nullptr;
+
+// GL_VERSION_1_3
+PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr;
+PFNGLSAMPLECOVERAGEPROC glSampleCoverage = nullptr;
+PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D = nullptr;
+PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D = nullptr;
+PFNGLCOMPRESSEDTEXIMAGE1DPROC glCompressedTexImage1D = nullptr;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D = nullptr;
+PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D = nullptr;
+PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D = nullptr;
+PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage = nullptr;
+PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture = nullptr;
+PFNGLMULTITEXCOORD1DPROC glMultiTexCoord1d = nullptr;
+PFNGLMULTITEXCOORD1DVPROC glMultiTexCoord1dv = nullptr;
+PFNGLMULTITEXCOORD1FPROC glMultiTexCoord1f = nullptr;
+PFNGLMULTITEXCOORD1FVPROC glMultiTexCoord1fv = nullptr;
+PFNGLMULTITEXCOORD1IPROC glMultiTexCoord1i = nullptr;
+PFNGLMULTITEXCOORD1IVPROC glMultiTexCoord1iv = nullptr;
+PFNGLMULTITEXCOORD1SPROC glMultiTexCoord1s = nullptr;
+PFNGLMULTITEXCOORD1SVPROC glMultiTexCoord1sv = nullptr;
+PFNGLMULTITEXCOORD2DPROC glMultiTexCoord2d = nullptr;
+PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv = nullptr;
+PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f = nullptr;
+PFNGLMULTITEXCOORD2FVPROC glMultiTexCoord2fv = nullptr;
+PFNGLMULTITEXCOORD2IPROC glMultiTexCoord2i = nullptr;
+PFNGLMULTITEXCOORD2IVPROC glMultiTexCoord2iv = nullptr;
+PFNGLMULTITEXCOORD2SPROC glMultiTexCoord2s = nullptr;
+PFNGLMULTITEXCOORD2SVPROC glMultiTexCoord2sv = nullptr;
+PFNGLMULTITEXCOORD3DPROC glMultiTexCoord3d = nullptr;
+PFNGLMULTITEXCOORD3DVPROC glMultiTexCoord3dv = nullptr;
+PFNGLMULTITEXCOORD3FPROC glMultiTexCoord3f = nullptr;
+PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv = nullptr;
+PFNGLMULTITEXCOORD3IPROC glMultiTexCoord3i = nullptr;
+PFNGLMULTITEXCOORD3IVPROC glMultiTexCoord3iv = nullptr;
+PFNGLMULTITEXCOORD3SPROC glMultiTexCoord3s = nullptr;
+PFNGLMULTITEXCOORD3SVPROC glMultiTexCoord3sv = nullptr;
+PFNGLMULTITEXCOORD4DPROC glMultiTexCoord4d = nullptr;
+PFNGLMULTITEXCOORD4DVPROC glMultiTexCoord4dv = nullptr;
+PFNGLMULTITEXCOORD4FPROC glMultiTexCoord4f = nullptr;
+PFNGLMULTITEXCOORD4FVPROC glMultiTexCoord4fv = nullptr;
+PFNGLMULTITEXCOORD4IPROC glMultiTexCoord4i = nullptr;
+PFNGLMULTITEXCOORD4IVPROC glMultiTexCoord4iv = nullptr;
+PFNGLMULTITEXCOORD4SPROC glMultiTexCoord4s = nullptr;
+PFNGLMULTITEXCOORD4SVPROC glMultiTexCoord4sv = nullptr;
+PFNGLLOADTRANSPOSEMATRIXFPROC glLoadTransposeMatrixf = nullptr;
+PFNGLLOADTRANSPOSEMATRIXDPROC glLoadTransposeMatrixd = nullptr;
+PFNGLMULTTRANSPOSEMATRIXFPROC glMultTransposeMatrixf = nullptr;
+PFNGLMULTTRANSPOSEMATRIXDPROC glMultTransposeMatrixd = nullptr;
+
+// GL_VERSION_1_4
+PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = nullptr;
+PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays = nullptr;
+PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements = nullptr;
+PFNGLPOINTPARAMETERFPROC glPointParameterf = nullptr;
+PFNGLPOINTPARAMETERFVPROC glPointParameterfv = nullptr;
+PFNGLPOINTPARAMETERIPROC glPointParameteri = nullptr;
+PFNGLPOINTPARAMETERIVPROC glPointParameteriv = nullptr;
+PFNGLFOGCOORDFPROC glFogCoordf = nullptr;
+PFNGLFOGCOORDFVPROC glFogCoordfv = nullptr;
+PFNGLFOGCOORDDPROC glFogCoordd = nullptr;
+PFNGLFOGCOORDDVPROC glFogCoorddv = nullptr;
+PFNGLFOGCOORDPOINTERPROC glFogCoordPointer = nullptr;
+PFNGLSECONDARYCOLOR3BPROC glSecondaryColor3b = nullptr;
+PFNGLSECONDARYCOLOR3BVPROC glSecondaryColor3bv = nullptr;
+PFNGLSECONDARYCOLOR3DPROC glSecondaryColor3d = nullptr;
+PFNGLSECONDARYCOLOR3DVPROC glSecondaryColor3dv = nullptr;
+PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f = nullptr;
+PFNGLSECONDARYCOLOR3FVPROC glSecondaryColor3fv = nullptr;
+PFNGLSECONDARYCOLOR3IPROC glSecondaryColor3i = nullptr;
+PFNGLSECONDARYCOLOR3IVPROC glSecondaryColor3iv = nullptr;
+PFNGLSECONDARYCOLOR3SPROC glSecondaryColor3s = nullptr;
+PFNGLSECONDARYCOLOR3SVPROC glSecondaryColor3sv = nullptr;
+PFNGLSECONDARYCOLOR3UBPROC glSecondaryColor3ub = nullptr;
+PFNGLSECONDARYCOLOR3UBVPROC glSecondaryColor3ubv = nullptr;
+PFNGLSECONDARYCOLOR3UIPROC glSecondaryColor3ui = nullptr;
+PFNGLSECONDARYCOLOR3UIVPROC glSecondaryColor3uiv = nullptr;
+PFNGLSECONDARYCOLOR3USPROC glSecondaryColor3us = nullptr;
+PFNGLSECONDARYCOLOR3USVPROC glSecondaryColor3usv = nullptr;
+PFNGLSECONDARYCOLORPOINTERPROC glSecondaryColorPointer = nullptr;
+PFNGLWINDOWPOS2DPROC glWindowPos2d = nullptr;
+PFNGLWINDOWPOS2DVPROC glWindowPos2dv = nullptr;
+PFNGLWINDOWPOS2FPROC glWindowPos2f = nullptr;
+PFNGLWINDOWPOS2FVPROC glWindowPos2fv = nullptr;
+PFNGLWINDOWPOS2IPROC glWindowPos2i = nullptr;
+PFNGLWINDOWPOS2IVPROC glWindowPos2iv = nullptr;
+PFNGLWINDOWPOS2SPROC glWindowPos2s = nullptr;
+PFNGLWINDOWPOS2SVPROC glWindowPos2sv = nullptr;
+PFNGLWINDOWPOS3DPROC glWindowPos3d = nullptr;
+PFNGLWINDOWPOS3DVPROC glWindowPos3dv = nullptr;
+PFNGLWINDOWPOS3FPROC glWindowPos3f = nullptr;
+PFNGLWINDOWPOS3FVPROC glWindowPos3fv = nullptr;
+PFNGLWINDOWPOS3IPROC glWindowPos3i = nullptr;
+PFNGLWINDOWPOS3IVPROC glWindowPos3iv = nullptr;
+PFNGLWINDOWPOS3SPROC glWindowPos3s = nullptr;
+PFNGLWINDOWPOS3SVPROC glWindowPos3sv = nullptr;
+
+// GL_VERSION_1_5
+PFNGLGENQUERIESPROC glGenQueries = nullptr;
+PFNGLDELETEQUERIESPROC glDeleteQueries = nullptr;
+PFNGLISQUERYPROC glIsQuery = nullptr;
+PFNGLBEGINQUERYPROC glBeginQuery = nullptr;
+PFNGLENDQUERYPROC glEndQuery = nullptr;
+PFNGLGETQUERYIVPROC glGetQueryiv = nullptr;
+PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv = nullptr;
+PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv = nullptr;
+PFNGLBINDBUFFERPROC glBindBuffer = nullptr;
+PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr;
+PFNGLGENBUFFERSPROC glGenBuffers = nullptr;
+PFNGLISBUFFERPROC glIsBuffer = nullptr;
+PFNGLBUFFERDATAPROC glBufferData = nullptr;
+PFNGLBUFFERSUBDATAPROC glBufferSubData = nullptr;
+PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData = nullptr;
+PFNGLMAPBUFFERPROC glMapBuffer = nullptr;
+PFNGLUNMAPBUFFERPROC glUnmapBuffer = nullptr;
+PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr;
+PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv = nullptr;
+
+// GL_VERSION_2_0
+PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate = nullptr;
+PFNGLDRAWBUFFERSPROC glDrawBuffers = nullptr;
+PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate = nullptr;
+PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate = nullptr;
+PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate = nullptr;
+PFNGLATTACHSHADERPROC glAttachShader = nullptr;
+PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = nullptr;
+PFNGLCOMPILESHADERPROC glCompileShader = nullptr;
+PFNGLCREATEPROGRAMPROC glCreateProgram = nullptr;
+PFNGLCREATESHADERPROC glCreateShader = nullptr;
+PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr;
+PFNGLDELETESHADERPROC glDeleteShader = nullptr;
+PFNGLDETACHSHADERPROC glDetachShader = nullptr;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = nullptr;
+PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = nullptr;
+PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib = nullptr;
+PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform = nullptr;
+PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders = nullptr;
+PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = nullptr;
+PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
+PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr;
+PFNGLGETSHADERIVPROC glGetShaderiv = nullptr;
+PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = nullptr;
+PFNGLGETSHADERSOURCEPROC glGetShaderSource = nullptr;
+PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
+PFNGLGETUNIFORMFVPROC glGetUniformfv = nullptr;
+PFNGLGETUNIFORMIVPROC glGetUniformiv = nullptr;
+PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv = nullptr;
+PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv = nullptr;
+PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv = nullptr;
+PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv = nullptr;
+PFNGLISPROGRAMPROC glIsProgram = nullptr;
+PFNGLISSHADERPROC glIsShader = nullptr;
+PFNGLLINKPROGRAMPROC glLinkProgram = nullptr;
+PFNGLSHADERSOURCEPROC glShaderSource = nullptr;
+PFNGLUSEPROGRAMPROC glUseProgram = nullptr;
+PFNGLUNIFORM1FPROC glUniform1f = nullptr;
+PFNGLUNIFORM2FPROC glUniform2f = nullptr;
+PFNGLUNIFORM3FPROC glUniform3f = nullptr;
+PFNGLUNIFORM4FPROC glUniform4f = nullptr;
+PFNGLUNIFORM1IPROC glUniform1i = nullptr;
+PFNGLUNIFORM2IPROC glUniform2i = nullptr;
+PFNGLUNIFORM3IPROC glUniform3i = nullptr;
+PFNGLUNIFORM4IPROC glUniform4i = nullptr;
+PFNGLUNIFORM1FVPROC glUniform1fv = nullptr;
+PFNGLUNIFORM2FVPROC glUniform2fv = nullptr;
+PFNGLUNIFORM3FVPROC glUniform3fv = nullptr;
+PFNGLUNIFORM4FVPROC glUniform4fv = nullptr;
+PFNGLUNIFORM1IVPROC glUniform1iv = nullptr;
+PFNGLUNIFORM2IVPROC glUniform2iv = nullptr;
+PFNGLUNIFORM3IVPROC glUniform3iv = nullptr;
+PFNGLUNIFORM4IVPROC glUniform4iv = nullptr;
+PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv = nullptr;
+PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv = nullptr;
+PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = nullptr;
+PFNGLVALIDATEPROGRAMPROC glValidateProgram = nullptr;
+PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d = nullptr;
+PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv = nullptr;
+PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f = nullptr;
+PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv = nullptr;
+PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s = nullptr;
+PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv = nullptr;
+PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d = nullptr;
+PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv = nullptr;
+PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f = nullptr;
+PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv = nullptr;
+PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s = nullptr;
+PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv = nullptr;
+PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d = nullptr;
+PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv = nullptr;
+PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f = nullptr;
+PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv = nullptr;
+PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s = nullptr;
+PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv = nullptr;
+PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv = nullptr;
+PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv = nullptr;
+PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv = nullptr;
+PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub = nullptr;
+PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv = nullptr;
+PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv = nullptr;
+PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv = nullptr;
+PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv = nullptr;
+PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d = nullptr;
+PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv = nullptr;
+PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = nullptr;
+PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv = nullptr;
+PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv = nullptr;
+PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s = nullptr;
+PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv = nullptr;
+PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv = nullptr;
+PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv = nullptr;
+PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv = nullptr;
+PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = nullptr;
+
+// GL_VERSION_2_1
+PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv = nullptr;
+PFNGLUNIFORMMATRIX3X2FVPROC glUniformMatrix3x2fv = nullptr;
+PFNGLUNIFORMMATRIX2X4FVPROC glUniformMatrix2x4fv = nullptr;
+PFNGLUNIFORMMATRIX4X2FVPROC glUniformMatrix4x2fv = nullptr;
+PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv = nullptr;
+PFNGLUNIFORMMATRIX4X3FVPROC glUniformMatrix4x3fv = nullptr;
+
+// GL_VERSION_3_0
+PFNGLCOLORMASKIPROC glColorMaski = nullptr;
+PFNGLGETBOOLEANI_VPROC glGetBooleani_v = nullptr;
+PFNGLGETINTEGERI_VPROC glGetIntegeri_v = nullptr;
+PFNGLENABLEIPROC glEnablei = nullptr;
+PFNGLDISABLEIPROC glDisablei = nullptr;
+PFNGLISENABLEDIPROC glIsEnabledi = nullptr;
+PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = nullptr;
+PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = nullptr;
+PFNGLBINDBUFFERRANGEPROC glBindBufferRange = nullptr;
+PFNGLBINDBUFFERBASEPROC glBindBufferBase = nullptr;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = nullptr;
+PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glGetTransformFeedbackVarying = nullptr;
+PFNGLCLAMPCOLORPROC glClampColor = nullptr;
+PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender = nullptr;
+PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender = nullptr;
+PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = nullptr;
+PFNGLGETVERTEXATTRIBIIVPROC glGetVertexAttribIiv = nullptr;
+PFNGLGETVERTEXATTRIBIUIVPROC glGetVertexAttribIuiv = nullptr;
+PFNGLVERTEXATTRIBI1IPROC glVertexAttribI1i = nullptr;
+PFNGLVERTEXATTRIBI2IPROC glVertexAttribI2i = nullptr;
+PFNGLVERTEXATTRIBI3IPROC glVertexAttribI3i = nullptr;
+PFNGLVERTEXATTRIBI4IPROC glVertexAttribI4i = nullptr;
+PFNGLVERTEXATTRIBI1UIPROC glVertexAttribI1ui = nullptr;
+PFNGLVERTEXATTRIBI2UIPROC glVertexAttribI2ui = nullptr;
+PFNGLVERTEXATTRIBI3UIPROC glVertexAttribI3ui = nullptr;
+PFNGLVERTEXATTRIBI4UIPROC glVertexAttribI4ui = nullptr;
+PFNGLVERTEXATTRIBI1IVPROC glVertexAttribI1iv = nullptr;
+PFNGLVERTEXATTRIBI2IVPROC glVertexAttribI2iv = nullptr;
+PFNGLVERTEXATTRIBI3IVPROC glVertexAttribI3iv = nullptr;
+PFNGLVERTEXATTRIBI4IVPROC glVertexAttribI4iv = nullptr;
+PFNGLVERTEXATTRIBI1UIVPROC glVertexAttribI1uiv = nullptr;
+PFNGLVERTEXATTRIBI2UIVPROC glVertexAttribI2uiv = nullptr;
+PFNGLVERTEXATTRIBI3UIVPROC glVertexAttribI3uiv = nullptr;
+PFNGLVERTEXATTRIBI4UIVPROC glVertexAttribI4uiv = nullptr;
+PFNGLVERTEXATTRIBI4BVPROC glVertexAttribI4bv = nullptr;
+PFNGLVERTEXATTRIBI4SVPROC glVertexAttribI4sv = nullptr;
+PFNGLVERTEXATTRIBI4UBVPROC glVertexAttribI4ubv = nullptr;
+PFNGLVERTEXATTRIBI4USVPROC glVertexAttribI4usv = nullptr;
+PFNGLGETUNIFORMUIVPROC glGetUniformuiv = nullptr;
+PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation = nullptr;
+PFNGLGETFRAGDATALOCATIONPROC glGetFragDataLocation = nullptr;
+PFNGLUNIFORM1UIPROC glUniform1ui = nullptr;
+PFNGLUNIFORM2UIPROC glUniform2ui = nullptr;
+PFNGLUNIFORM3UIPROC glUniform3ui = nullptr;
+PFNGLUNIFORM4UIPROC glUniform4ui = nullptr;
+PFNGLUNIFORM1UIVPROC glUniform1uiv = nullptr;
+PFNGLUNIFORM2UIVPROC glUniform2uiv = nullptr;
+PFNGLUNIFORM3UIVPROC glUniform3uiv = nullptr;
+PFNGLUNIFORM4UIVPROC glUniform4uiv = nullptr;
+PFNGLTEXPARAMETERIIVPROC glTexParameterIiv = nullptr;
+PFNGLTEXPARAMETERIUIVPROC glTexParameterIuiv = nullptr;
+PFNGLGETTEXPARAMETERIIVPROC glGetTexParameterIiv = nullptr;
+PFNGLGETTEXPARAMETERIUIVPROC glGetTexParameterIuiv = nullptr;
+PFNGLCLEARBUFFERIVPROC glClearBufferiv = nullptr;
+PFNGLCLEARBUFFERUIVPROC glClearBufferuiv = nullptr;
+PFNGLCLEARBUFFERFVPROC glClearBufferfv = nullptr;
+PFNGLCLEARBUFFERFIPROC glClearBufferfi = nullptr;
+PFNGLGETSTRINGIPROC glGetStringi = nullptr;
+PFNGLISRENDERBUFFERPROC glIsRenderbuffer = nullptr;
+PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = nullptr;
+PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = nullptr;
+PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = nullptr;
+PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = nullptr;
+PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv = nullptr;
+PFNGLISFRAMEBUFFERPROC glIsFramebuffer = nullptr;
+PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = nullptr;
+PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = nullptr;
+PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = nullptr;
+PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = nullptr;
+PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D = nullptr;
+PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = nullptr;
+PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D = nullptr;
+PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = nullptr;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv = nullptr;
+PFNGLGENERATEMIPMAPPROC glGenerateMipmap = nullptr;
+PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = nullptr;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = nullptr;
+PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = nullptr;
+PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr;
+PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange = nullptr;
+PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr;
+PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = nullptr;
+PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr;
+PFNGLISVERTEXARRAYPROC glIsVertexArray = nullptr;
+
+// GL_VERSION_3_1
+PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced = nullptr;
+PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced = nullptr;
+PFNGLTEXBUFFERPROC glTexBuffer = nullptr;
+PFNGLPRIMITIVERESTARTINDEXPROC glPrimitiveRestartIndex = nullptr;
+PFNGLCOPYBUFFERSUBDATAPROC glCopyBufferSubData = nullptr;
+PFNGLGETUNIFORMINDICESPROC glGetUniformIndices = nullptr;
+PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv = nullptr;
+PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformName = nullptr;
+PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex = nullptr;
+PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv = nullptr;
+PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName = nullptr;
+PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding = nullptr;
+
+// GL_VERSION_3_2
+PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex = nullptr;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glDrawRangeElementsBaseVertex = nullptr;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex = nullptr;
+PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glMultiDrawElementsBaseVertex = nullptr;
+PFNGLPROVOKINGVERTEXPROC glProvokingVertex = nullptr;
+PFNGLFENCESYNCPROC glFenceSync = nullptr;
+PFNGLISSYNCPROC glIsSync = nullptr;
+PFNGLDELETESYNCPROC glDeleteSync = nullptr;
+PFNGLCLIENTWAITSYNCPROC glClientWaitSync = nullptr;
+PFNGLWAITSYNCPROC glWaitSync = nullptr;
+PFNGLGETINTEGER64VPROC glGetInteger64v = nullptr;
+PFNGLGETSYNCIVPROC glGetSynciv = nullptr;
+PFNGLGETINTEGER64I_VPROC glGetInteger64i_v = nullptr;
+PFNGLGETBUFFERPARAMETERI64VPROC glGetBufferParameteri64v = nullptr;
+PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture = nullptr;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample = nullptr;
+PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = nullptr;
+PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = nullptr;
+PFNGLSAMPLEMASKIPROC glSampleMaski = nullptr;
+
+// GL_VERSION_3_3
+PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glBindFragDataLocationIndexed = nullptr;
+PFNGLGETFRAGDATAINDEXPROC glGetFragDataIndex = nullptr;
+PFNGLGENSAMPLERSPROC glGenSamplers = nullptr;
+PFNGLDELETESAMPLERSPROC glDeleteSamplers = nullptr;
+PFNGLISSAMPLERPROC glIsSampler = nullptr;
+PFNGLBINDSAMPLERPROC glBindSampler = nullptr;
+PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri = nullptr;
+PFNGLSAMPLERPARAMETERIVPROC glSamplerParameteriv = nullptr;
+PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf = nullptr;
+PFNGLSAMPLERPARAMETERFVPROC glSamplerParameterfv = nullptr;
+PFNGLSAMPLERPARAMETERIIVPROC glSamplerParameterIiv = nullptr;
+PFNGLSAMPLERPARAMETERIUIVPROC glSamplerParameterIuiv = nullptr;
+PFNGLGETSAMPLERPARAMETERIVPROC glGetSamplerParameteriv = nullptr;
+PFNGLGETSAMPLERPARAMETERIIVPROC glGetSamplerParameterIiv = nullptr;
+PFNGLGETSAMPLERPARAMETERFVPROC glGetSamplerParameterfv = nullptr;
+PFNGLGETSAMPLERPARAMETERIUIVPROC glGetSamplerParameterIuiv = nullptr;
+PFNGLQUERYCOUNTERPROC glQueryCounter = nullptr;
+PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v = nullptr;
+PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = nullptr;
+PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor = nullptr;
+PFNGLVERTEXATTRIBP1UIPROC glVertexAttribP1ui = nullptr;
+PFNGLVERTEXATTRIBP1UIVPROC glVertexAttribP1uiv = nullptr;
+PFNGLVERTEXATTRIBP2UIPROC glVertexAttribP2ui = nullptr;
+PFNGLVERTEXATTRIBP2UIVPROC glVertexAttribP2uiv = nullptr;
+PFNGLVERTEXATTRIBP3UIPROC glVertexAttribP3ui = nullptr;
+PFNGLVERTEXATTRIBP3UIVPROC glVertexAttribP3uiv = nullptr;
+PFNGLVERTEXATTRIBP4UIPROC glVertexAttribP4ui = nullptr;
+PFNGLVERTEXATTRIBP4UIVPROC glVertexAttribP4uiv = nullptr;
+PFNGLVERTEXP2UIPROC glVertexP2ui = nullptr;
+PFNGLVERTEXP2UIVPROC glVertexP2uiv = nullptr;
+PFNGLVERTEXP3UIPROC glVertexP3ui = nullptr;
+PFNGLVERTEXP3UIVPROC glVertexP3uiv = nullptr;
+PFNGLVERTEXP4UIPROC glVertexP4ui = nullptr;
+PFNGLVERTEXP4UIVPROC glVertexP4uiv = nullptr;
+PFNGLTEXCOORDP1UIPROC glTexCoordP1ui = nullptr;
+PFNGLTEXCOORDP1UIVPROC glTexCoordP1uiv = nullptr;
+PFNGLTEXCOORDP2UIPROC glTexCoordP2ui = nullptr;
+PFNGLTEXCOORDP2UIVPROC glTexCoordP2uiv = nullptr;
+PFNGLTEXCOORDP3UIPROC glTexCoordP3ui = nullptr;
+PFNGLTEXCOORDP3UIVPROC glTexCoordP3uiv = nullptr;
+PFNGLTEXCOORDP4UIPROC glTexCoordP4ui = nullptr;
+PFNGLTEXCOORDP4UIVPROC glTexCoordP4uiv = nullptr;
+PFNGLMULTITEXCOORDP1UIPROC glMultiTexCoordP1ui = nullptr;
+PFNGLMULTITEXCOORDP1UIVPROC glMultiTexCoordP1uiv = nullptr;
+PFNGLMULTITEXCOORDP2UIPROC glMultiTexCoordP2ui = nullptr;
+PFNGLMULTITEXCOORDP2UIVPROC glMultiTexCoordP2uiv = nullptr;
+PFNGLMULTITEXCOORDP3UIPROC glMultiTexCoordP3ui = nullptr;
+PFNGLMULTITEXCOORDP3UIVPROC glMultiTexCoordP3uiv = nullptr;
+PFNGLMULTITEXCOORDP4UIPROC glMultiTexCoordP4ui = nullptr;
+PFNGLMULTITEXCOORDP4UIVPROC glMultiTexCoordP4uiv = nullptr;
+PFNGLNORMALP3UIPROC glNormalP3ui = nullptr;
+PFNGLNORMALP3UIVPROC glNormalP3uiv = nullptr;
+PFNGLCOLORP3UIPROC glColorP3ui = nullptr;
+PFNGLCOLORP3UIVPROC glColorP3uiv = nullptr;
+PFNGLCOLORP4UIPROC glColorP4ui = nullptr;
+PFNGLCOLORP4UIVPROC glColorP4uiv = nullptr;
+PFNGLSECONDARYCOLORP3UIPROC glSecondaryColorP3ui = nullptr;
+PFNGLSECONDARYCOLORP3UIVPROC glSecondaryColorP3uiv = nullptr;
+
+// GL_VERSION_4_0
+PFNGLMINSAMPLESHADINGPROC glMinSampleShading = nullptr;
+PFNGLBLENDEQUATIONIPROC glBlendEquationi = nullptr;
+PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei = nullptr;
+PFNGLBLENDFUNCIPROC glBlendFunci = nullptr;
+PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei = nullptr;
+PFNGLDRAWARRAYSINDIRECTPROC glDrawArraysIndirect = nullptr;
+PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect = nullptr;
+PFNGLUNIFORM1DPROC glUniform1d = nullptr;
+PFNGLUNIFORM2DPROC glUniform2d = nullptr;
+PFNGLUNIFORM3DPROC glUniform3d = nullptr;
+PFNGLUNIFORM4DPROC glUniform4d = nullptr;
+PFNGLUNIFORM1DVPROC glUniform1dv = nullptr;
+PFNGLUNIFORM2DVPROC glUniform2dv = nullptr;
+PFNGLUNIFORM3DVPROC glUniform3dv = nullptr;
+PFNGLUNIFORM4DVPROC glUniform4dv = nullptr;
+PFNGLUNIFORMMATRIX2DVPROC glUniformMatrix2dv = nullptr;
+PFNGLUNIFORMMATRIX3DVPROC glUniformMatrix3dv = nullptr;
+PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv = nullptr;
+PFNGLUNIFORMMATRIX2X3DVPROC glUniformMatrix2x3dv = nullptr;
+PFNGLUNIFORMMATRIX2X4DVPROC glUniformMatrix2x4dv = nullptr;
+PFNGLUNIFORMMATRIX3X2DVPROC glUniformMatrix3x2dv = nullptr;
+PFNGLUNIFORMMATRIX3X4DVPROC glUniformMatrix3x4dv = nullptr;
+PFNGLUNIFORMMATRIX4X2DVPROC glUniformMatrix4x2dv = nullptr;
+PFNGLUNIFORMMATRIX4X3DVPROC glUniformMatrix4x3dv = nullptr;
+PFNGLGETUNIFORMDVPROC glGetUniformdv = nullptr;
+PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glGetSubroutineUniformLocation = nullptr;
+PFNGLGETSUBROUTINEINDEXPROC glGetSubroutineIndex = nullptr;
+PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glGetActiveSubroutineUniformiv = nullptr;
+PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glGetActiveSubroutineUniformName = nullptr;
+PFNGLGETACTIVESUBROUTINENAMEPROC glGetActiveSubroutineName = nullptr;
+PFNGLUNIFORMSUBROUTINESUIVPROC glUniformSubroutinesuiv = nullptr;
+PFNGLGETUNIFORMSUBROUTINEUIVPROC glGetUniformSubroutineuiv = nullptr;
+PFNGLGETPROGRAMSTAGEIVPROC glGetProgramStageiv = nullptr;
+PFNGLPATCHPARAMETERIPROC glPatchParameteri = nullptr;
+PFNGLPATCHPARAMETERFVPROC glPatchParameterfv = nullptr;
+PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback = nullptr;
+PFNGLDELETETRANSFORMFEEDBACKSPROC glDeleteTransformFeedbacks = nullptr;
+PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks = nullptr;
+PFNGLISTRANSFORMFEEDBACKPROC glIsTransformFeedback = nullptr;
+PFNGLPAUSETRANSFORMFEEDBACKPROC glPauseTransformFeedback = nullptr;
+PFNGLRESUMETRANSFORMFEEDBACKPROC glResumeTransformFeedback = nullptr;
+PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback = nullptr;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glDrawTransformFeedbackStream = nullptr;
+PFNGLBEGINQUERYINDEXEDPROC glBeginQueryIndexed = nullptr;
+PFNGLENDQUERYINDEXEDPROC glEndQueryIndexed = nullptr;
+PFNGLGETQUERYINDEXEDIVPROC glGetQueryIndexediv = nullptr;
+
+// GL_VERSION_4_1
+PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler = nullptr;
+PFNGLSHADERBINARYPROC glShaderBinary = nullptr;
+PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat = nullptr;
+PFNGLDEPTHRANGEFPROC glDepthRangef = nullptr;
+PFNGLCLEARDEPTHFPROC glClearDepthf = nullptr;
+PFNGLGETPROGRAMBINARYPROC glGetProgramBinary = nullptr;
+PFNGLPROGRAMBINARYPROC glProgramBinary = nullptr;
+PFNGLPROGRAMPARAMETERIPROC glProgramParameteri = nullptr;
+PFNGLUSEPROGRAMSTAGESPROC glUseProgramStages = nullptr;
+PFNGLACTIVESHADERPROGRAMPROC glActiveShaderProgram = nullptr;
+PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv = nullptr;
+PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline = nullptr;
+PFNGLDELETEPROGRAMPIPELINESPROC glDeleteProgramPipelines = nullptr;
+PFNGLGENPROGRAMPIPELINESPROC glGenProgramPipelines = nullptr;
+PFNGLISPROGRAMPIPELINEPROC glIsProgramPipeline = nullptr;
+PFNGLGETPROGRAMPIPELINEIVPROC glGetProgramPipelineiv = nullptr;
+PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = nullptr;
+PFNGLPROGRAMUNIFORM1IVPROC glProgramUniform1iv = nullptr;
+PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr;
+PFNGLPROGRAMUNIFORM1FVPROC glProgramUniform1fv = nullptr;
+PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr;
+PFNGLPROGRAMUNIFORM1DVPROC glProgramUniform1dv = nullptr;
+PFNGLPROGRAMUNIFORM1UIPROC glProgramUniform1ui = nullptr;
+PFNGLPROGRAMUNIFORM1UIVPROC glProgramUniform1uiv = nullptr;
+PFNGLPROGRAMUNIFORM2IPROC glProgramUniform2i = nullptr;
+PFNGLPROGRAMUNIFORM2IVPROC glProgramUniform2iv = nullptr;
+PFNGLPROGRAMUNIFORM2FPROC glProgramUniform2f = nullptr;
+PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv = nullptr;
+PFNGLPROGRAMUNIFORM2DPROC glProgramUniform2d = nullptr;
+PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv = nullptr;
+PFNGLPROGRAMUNIFORM2UIPROC glProgramUniform2ui = nullptr;
+PFNGLPROGRAMUNIFORM2UIVPROC glProgramUniform2uiv = nullptr;
+PFNGLPROGRAMUNIFORM3IPROC glProgramUniform3i = nullptr;
+PFNGLPROGRAMUNIFORM3IVPROC glProgramUniform3iv = nullptr;
+PFNGLPROGRAMUNIFORM3FPROC glProgramUniform3f = nullptr;
+PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv = nullptr;
+PFNGLPROGRAMUNIFORM3DPROC glProgramUniform3d = nullptr;
+PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv = nullptr;
+PFNGLPROGRAMUNIFORM3UIPROC glProgramUniform3ui = nullptr;
+PFNGLPROGRAMUNIFORM3UIVPROC glProgramUniform3uiv = nullptr;
+PFNGLPROGRAMUNIFORM4IPROC glProgramUniform4i = nullptr;
+PFNGLPROGRAMUNIFORM4IVPROC glProgramUniform4iv = nullptr;
+PFNGLPROGRAMUNIFORM4FPROC glProgramUniform4f = nullptr;
+PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv = nullptr;
+PFNGLPROGRAMUNIFORM4DPROC glProgramUniform4d = nullptr;
+PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv = nullptr;
+PFNGLPROGRAMUNIFORM4UIPROC glProgramUniform4ui = nullptr;
+PFNGLPROGRAMUNIFORM4UIVPROC glProgramUniform4uiv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX2FVPROC glProgramUniformMatrix2fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX3FVPROC glProgramUniformMatrix3fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX2DVPROC glProgramUniformMatrix2dv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX3DVPROC glProgramUniformMatrix3dv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glProgramUniformMatrix2x3fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glProgramUniformMatrix3x2fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glProgramUniformMatrix2x4fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glProgramUniformMatrix4x2fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glProgramUniformMatrix3x4fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glProgramUniformMatrix4x3fv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glProgramUniformMatrix2x3dv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glProgramUniformMatrix3x2dv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glProgramUniformMatrix2x4dv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glProgramUniformMatrix4x2dv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glProgramUniformMatrix3x4dv = nullptr;
+PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glProgramUniformMatrix4x3dv = nullptr;
+PFNGLVALIDATEPROGRAMPIPELINEPROC glValidateProgramPipeline = nullptr;
+PFNGLGETPROGRAMPIPELINEINFOLOGPROC glGetProgramPipelineInfoLog = nullptr;
+PFNGLVERTEXATTRIBL1DPROC glVertexAttribL1d = nullptr;
+PFNGLVERTEXATTRIBL2DPROC glVertexAttribL2d = nullptr;
+PFNGLVERTEXATTRIBL3DPROC glVertexAttribL3d = nullptr;
+PFNGLVERTEXATTRIBL4DPROC glVertexAttribL4d = nullptr;
+PFNGLVERTEXATTRIBL1DVPROC glVertexAttribL1dv = nullptr;
+PFNGLVERTEXATTRIBL2DVPROC glVertexAttribL2dv = nullptr;
+PFNGLVERTEXATTRIBL3DVPROC glVertexAttribL3dv = nullptr;
+PFNGLVERTEXATTRIBL4DVPROC glVertexAttribL4dv = nullptr;
+PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer = nullptr;
+PFNGLGETVERTEXATTRIBLDVPROC glGetVertexAttribLdv = nullptr;
+PFNGLVIEWPORTARRAYVPROC glViewportArrayv = nullptr;
+PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf = nullptr;
+PFNGLVIEWPORTINDEXEDFVPROC glViewportIndexedfv = nullptr;
+PFNGLSCISSORARRAYVPROC glScissorArrayv = nullptr;
+PFNGLSCISSORINDEXEDPROC glScissorIndexed = nullptr;
+PFNGLSCISSORINDEXEDVPROC glScissorIndexedv = nullptr;
+PFNGLDEPTHRANGEARRAYVPROC glDepthRangeArrayv = nullptr;
+PFNGLDEPTHRANGEINDEXEDPROC glDepthRangeIndexed = nullptr;
+PFNGLGETFLOATI_VPROC glGetFloati_v = nullptr;
+PFNGLGETDOUBLEI_VPROC glGetDoublei_v = nullptr;
+
+// GL_VERSION_4_2
+PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glDrawArraysInstancedBaseInstance = nullptr;
+PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glDrawElementsInstancedBaseInstance = nullptr;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glDrawElementsInstancedBaseVertexBaseInstance = nullptr;
+PFNGLGETINTERNALFORMATIVPROC glGetInternalformativ = nullptr;
+PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glGetActiveAtomicCounterBufferiv = nullptr;
+PFNGLBINDIMAGETEXTUREPROC glBindImageTexture = nullptr;
+PFNGLMEMORYBARRIERPROC glMemoryBarrier = nullptr;
+PFNGLTEXSTORAGE1DPROC glTexStorage1D = nullptr;
+PFNGLTEXSTORAGE2DPROC glTexStorage2D = nullptr;
+PFNGLTEXSTORAGE3DPROC glTexStorage3D = nullptr;
+PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glDrawTransformFeedbackInstanced = nullptr;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glDrawTransformFeedbackStreamInstanced = nullptr;
+
+// GL_VERSION_4_3
+PFNGLCLEARBUFFERDATAPROC glClearBufferData = nullptr;
+PFNGLCLEARBUFFERSUBDATAPROC glClearBufferSubData = nullptr;
+PFNGLDISPATCHCOMPUTEPROC glDispatchCompute = nullptr;
+PFNGLDISPATCHCOMPUTEINDIRECTPROC glDispatchComputeIndirect = nullptr;
+PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData = nullptr;
+PFNGLFRAMEBUFFERPARAMETERIPROC glFramebufferParameteri = nullptr;
+PFNGLGETFRAMEBUFFERPARAMETERIVPROC glGetFramebufferParameteriv = nullptr;
+PFNGLGETINTERNALFORMATI64VPROC glGetInternalformati64v = nullptr;
+PFNGLINVALIDATETEXSUBIMAGEPROC glInvalidateTexSubImage = nullptr;
+PFNGLINVALIDATETEXIMAGEPROC glInvalidateTexImage = nullptr;
+PFNGLINVALIDATEBUFFERSUBDATAPROC glInvalidateBufferSubData = nullptr;
+PFNGLINVALIDATEBUFFERDATAPROC glInvalidateBufferData = nullptr;
+PFNGLINVALIDATEFRAMEBUFFERPROC glInvalidateFramebuffer = nullptr;
+PFNGLINVALIDATESUBFRAMEBUFFERPROC glInvalidateSubFramebuffer = nullptr;
+PFNGLMULTIDRAWARRAYSINDIRECTPROC glMultiDrawArraysIndirect = nullptr;
+PFNGLMULTIDRAWELEMENTSINDIRECTPROC glMultiDrawElementsIndirect = nullptr;
+PFNGLGETPROGRAMINTERFACEIVPROC glGetProgramInterfaceiv = nullptr;
+PFNGLGETPROGRAMRESOURCEINDEXPROC glGetProgramResourceIndex = nullptr;
+PFNGLGETPROGRAMRESOURCENAMEPROC glGetProgramResourceName = nullptr;
+PFNGLGETPROGRAMRESOURCEIVPROC glGetProgramResourceiv = nullptr;
+PFNGLGETPROGRAMRESOURCELOCATIONPROC glGetProgramResourceLocation = nullptr;
+PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glGetProgramResourceLocationIndex = nullptr;
+PFNGLSHADERSTORAGEBLOCKBINDINGPROC glShaderStorageBlockBinding = nullptr;
+PFNGLTEXBUFFERRANGEPROC glTexBufferRange = nullptr;
+PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample = nullptr;
+PFNGLTEXSTORAGE3DMULTISAMPLEPROC glTexStorage3DMultisample = nullptr;
+PFNGLTEXTUREVIEWPROC glTextureView = nullptr;
+PFNGLBINDVERTEXBUFFERPROC glBindVertexBuffer = nullptr;
+PFNGLVERTEXATTRIBFORMATPROC glVertexAttribFormat = nullptr;
+PFNGLVERTEXATTRIBIFORMATPROC glVertexAttribIFormat = nullptr;
+PFNGLVERTEXATTRIBLFORMATPROC glVertexAttribLFormat = nullptr;
+PFNGLVERTEXATTRIBBINDINGPROC glVertexAttribBinding = nullptr;
+PFNGLVERTEXBINDINGDIVISORPROC glVertexBindingDivisor = nullptr;
+PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl = nullptr;
+PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert = nullptr;
+PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback = nullptr;
+PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog = nullptr;
+PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup = nullptr;
+PFNGLPOPDEBUGGROUPPROC glPopDebugGroup = nullptr;
+PFNGLOBJECTLABELPROC glObjectLabel = nullptr;
+PFNGLGETOBJECTLABELPROC glGetObjectLabel = nullptr;
+PFNGLOBJECTPTRLABELPROC glObjectPtrLabel = nullptr;
+PFNGLGETOBJECTPTRLABELPROC glGetObjectPtrLabel = nullptr;
+
+// GL_VERSION_4_4
+PFNGLBUFFERSTORAGEPROC glBufferStorage = nullptr;
+PFNGLCLEARTEXIMAGEPROC glClearTexImage = nullptr;
+PFNGLCLEARTEXSUBIMAGEPROC glClearTexSubImage = nullptr;
+PFNGLBINDBUFFERSBASEPROC glBindBuffersBase = nullptr;
+PFNGLBINDBUFFERSRANGEPROC glBindBuffersRange = nullptr;
+PFNGLBINDTEXTURESPROC glBindTextures = nullptr;
+PFNGLBINDSAMPLERSPROC glBindSamplers = nullptr;
+PFNGLBINDIMAGETEXTURESPROC glBindImageTextures = nullptr;
+PFNGLBINDVERTEXBUFFERSPROC glBindVertexBuffers = nullptr;
+
+// GL_VERSION_4_5
+PFNGLCLIPCONTROLPROC glClipControl = nullptr;
+PFNGLCREATETRANSFORMFEEDBACKSPROC glCreateTransformFeedbacks = nullptr;
+PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glTransformFeedbackBufferBase = nullptr;
+PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glTransformFeedbackBufferRange = nullptr;
+PFNGLGETTRANSFORMFEEDBACKIVPROC glGetTransformFeedbackiv = nullptr;
+PFNGLGETTRANSFORMFEEDBACKI_VPROC glGetTransformFeedbacki_v = nullptr;
+PFNGLGETTRANSFORMFEEDBACKI64_VPROC glGetTransformFeedbacki64_v = nullptr;
+PFNGLCREATEBUFFERSPROC glCreateBuffers = nullptr;
+PFNGLNAMEDBUFFERSTORAGEPROC glNamedBufferStorage = nullptr;
+PFNGLNAMEDBUFFERDATAPROC glNamedBufferData = nullptr;
+PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData = nullptr;
+PFNGLCOPYNAMEDBUFFERSUBDATAPROC glCopyNamedBufferSubData = nullptr;
+PFNGLCLEARNAMEDBUFFERDATAPROC glClearNamedBufferData = nullptr;
+PFNGLCLEARNAMEDBUFFERSUBDATAPROC glClearNamedBufferSubData = nullptr;
+PFNGLMAPNAMEDBUFFERPROC glMapNamedBuffer = nullptr;
+PFNGLMAPNAMEDBUFFERRANGEPROC glMapNamedBufferRange = nullptr;
+PFNGLUNMAPNAMEDBUFFERPROC glUnmapNamedBuffer = nullptr;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glFlushMappedNamedBufferRange = nullptr;
+PFNGLGETNAMEDBUFFERPARAMETERIVPROC glGetNamedBufferParameteriv = nullptr;
+PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glGetNamedBufferParameteri64v = nullptr;
+PFNGLGETNAMEDBUFFERPOINTERVPROC glGetNamedBufferPointerv = nullptr;
+PFNGLGETNAMEDBUFFERSUBDATAPROC glGetNamedBufferSubData = nullptr;
+PFNGLCREATEFRAMEBUFFERSPROC glCreateFramebuffers = nullptr;
+PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glNamedFramebufferRenderbuffer = nullptr;
+PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glNamedFramebufferParameteri = nullptr;
+PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glNamedFramebufferTexture = nullptr;
+PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glNamedFramebufferTextureLayer = nullptr;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glNamedFramebufferDrawBuffer = nullptr;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glNamedFramebufferDrawBuffers = nullptr;
+PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glNamedFramebufferReadBuffer = nullptr;
+PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glInvalidateNamedFramebufferData = nullptr;
+PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glInvalidateNamedFramebufferSubData = nullptr;
+PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glClearNamedFramebufferiv = nullptr;
+PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glClearNamedFramebufferuiv = nullptr;
+PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glClearNamedFramebufferfv = nullptr;
+PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glClearNamedFramebufferfi = nullptr;
+PFNGLBLITNAMEDFRAMEBUFFERPROC glBlitNamedFramebuffer = nullptr;
+PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glCheckNamedFramebufferStatus = nullptr;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glGetNamedFramebufferParameteriv = nullptr;
+PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetNamedFramebufferAttachmentParameteriv = nullptr;
+PFNGLCREATERENDERBUFFERSPROC glCreateRenderbuffers = nullptr;
+PFNGLNAMEDRENDERBUFFERSTORAGEPROC glNamedRenderbufferStorage = nullptr;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glNamedRenderbufferStorageMultisample = nullptr;
+PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glGetNamedRenderbufferParameteriv = nullptr;
+PFNGLCREATETEXTURESPROC glCreateTextures = nullptr;
+PFNGLTEXTUREBUFFERPROC glTextureBuffer = nullptr;
+PFNGLTEXTUREBUFFERRANGEPROC glTextureBufferRange = nullptr;
+PFNGLTEXTURESTORAGE1DPROC glTextureStorage1D = nullptr;
+PFNGLTEXTURESTORAGE2DPROC glTextureStorage2D = nullptr;
+PFNGLTEXTURESTORAGE3DPROC glTextureStorage3D = nullptr;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glTextureStorage2DMultisample = nullptr;
+PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glTextureStorage3DMultisample = nullptr;
+PFNGLTEXTURESUBIMAGE1DPROC glTextureSubImage1D = nullptr;
+PFNGLTEXTURESUBIMAGE2DPROC glTextureSubImage2D = nullptr;
+PFNGLTEXTURESUBIMAGE3DPROC glTextureSubImage3D = nullptr;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glCompressedTextureSubImage1D = nullptr;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glCompressedTextureSubImage2D = nullptr;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glCompressedTextureSubImage3D = nullptr;
+PFNGLCOPYTEXTURESUBIMAGE1DPROC glCopyTextureSubImage1D = nullptr;
+PFNGLCOPYTEXTURESUBIMAGE2DPROC glCopyTextureSubImage2D = nullptr;
+PFNGLCOPYTEXTURESUBIMAGE3DPROC glCopyTextureSubImage3D = nullptr;
+PFNGLTEXTUREPARAMETERFPROC glTextureParameterf = nullptr;
+PFNGLTEXTUREPARAMETERFVPROC glTextureParameterfv = nullptr;
+PFNGLTEXTUREPARAMETERIPROC glTextureParameteri = nullptr;
+PFNGLTEXTUREPARAMETERIIVPROC glTextureParameterIiv = nullptr;
+PFNGLTEXTUREPARAMETERIUIVPROC glTextureParameterIuiv = nullptr;
+PFNGLTEXTUREPARAMETERIVPROC glTextureParameteriv = nullptr;
+PFNGLGENERATETEXTUREMIPMAPPROC glGenerateTextureMipmap = nullptr;
+PFNGLBINDTEXTUREUNITPROC glBindTextureUnit = nullptr;
+PFNGLGETTEXTUREIMAGEPROC glGetTextureImage = nullptr;
+PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glGetCompressedTextureImage = nullptr;
+PFNGLGETTEXTURELEVELPARAMETERFVPROC glGetTextureLevelParameterfv = nullptr;
+PFNGLGETTEXTURELEVELPARAMETERIVPROC glGetTextureLevelParameteriv = nullptr;
+PFNGLGETTEXTUREPARAMETERFVPROC glGetTextureParameterfv = nullptr;
+PFNGLGETTEXTUREPARAMETERIIVPROC glGetTextureParameterIiv = nullptr;
+PFNGLGETTEXTUREPARAMETERIUIVPROC glGetTextureParameterIuiv = nullptr;
+PFNGLGETTEXTUREPARAMETERIVPROC glGetTextureParameteriv = nullptr;
+PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays = nullptr;
+PFNGLDISABLEVERTEXARRAYATTRIBPROC glDisableVertexArrayAttrib = nullptr;
+PFNGLENABLEVERTEXARRAYATTRIBPROC glEnableVertexArrayAttrib = nullptr;
+PFNGLVERTEXARRAYELEMENTBUFFERPROC glVertexArrayElementBuffer = nullptr;
+PFNGLVERTEXARRAYVERTEXBUFFERPROC glVertexArrayVertexBuffer = nullptr;
+PFNGLVERTEXARRAYVERTEXBUFFERSPROC glVertexArrayVertexBuffers = nullptr;
+PFNGLVERTEXARRAYATTRIBBINDINGPROC glVertexArrayAttribBinding = nullptr;
+PFNGLVERTEXARRAYATTRIBFORMATPROC glVertexArrayAttribFormat = nullptr;
+PFNGLVERTEXARRAYATTRIBIFORMATPROC glVertexArrayAttribIFormat = nullptr;
+PFNGLVERTEXARRAYATTRIBLFORMATPROC glVertexArrayAttribLFormat = nullptr;
+PFNGLVERTEXARRAYBINDINGDIVISORPROC glVertexArrayBindingDivisor = nullptr;
+PFNGLGETVERTEXARRAYIVPROC glGetVertexArrayiv = nullptr;
+PFNGLGETVERTEXARRAYINDEXEDIVPROC glGetVertexArrayIndexediv = nullptr;
+PFNGLGETVERTEXARRAYINDEXED64IVPROC glGetVertexArrayIndexed64iv = nullptr;
+PFNGLCREATESAMPLERSPROC glCreateSamplers = nullptr;
+PFNGLCREATEPROGRAMPIPELINESPROC glCreateProgramPipelines = nullptr;
+PFNGLCREATEQUERIESPROC glCreateQueries = nullptr;
+PFNGLGETQUERYBUFFEROBJECTI64VPROC glGetQueryBufferObjecti64v = nullptr;
+PFNGLGETQUERYBUFFEROBJECTIVPROC glGetQueryBufferObjectiv = nullptr;
+PFNGLGETQUERYBUFFEROBJECTUI64VPROC glGetQueryBufferObjectui64v = nullptr;
+PFNGLGETQUERYBUFFEROBJECTUIVPROC glGetQueryBufferObjectuiv = nullptr;
+PFNGLMEMORYBARRIERBYREGIONPROC glMemoryBarrierByRegion = nullptr;
+PFNGLGETTEXTURESUBIMAGEPROC glGetTextureSubImage = nullptr;
+PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glGetCompressedTextureSubImage = nullptr;
+PFNGLGETGRAPHICSRESETSTATUSPROC glGetGraphicsResetStatus = nullptr;
+PFNGLGETNCOMPRESSEDTEXIMAGEPROC glGetnCompressedTexImage = nullptr;
+PFNGLGETNTEXIMAGEPROC glGetnTexImage = nullptr;
+PFNGLGETNUNIFORMDVPROC glGetnUniformdv = nullptr;
+PFNGLGETNUNIFORMFVPROC glGetnUniformfv = nullptr;
+PFNGLGETNUNIFORMIVPROC glGetnUniformiv = nullptr;
+PFNGLGETNUNIFORMUIVPROC glGetnUniformuiv = nullptr;
+PFNGLREADNPIXELSPROC glReadnPixels = nullptr;
+PFNGLGETNMAPDVPROC glGetnMapdv = nullptr;
+PFNGLGETNMAPFVPROC glGetnMapfv = nullptr;
+PFNGLGETNMAPIVPROC glGetnMapiv = nullptr;
+PFNGLGETNPIXELMAPFVPROC glGetnPixelMapfv = nullptr;
+PFNGLGETNPIXELMAPUIVPROC glGetnPixelMapuiv = nullptr;
+PFNGLGETNPIXELMAPUSVPROC glGetnPixelMapusv = nullptr;
+PFNGLGETNPOLYGONSTIPPLEPROC glGetnPolygonStipple = nullptr;
+PFNGLGETNCOLORTABLEPROC glGetnColorTable = nullptr;
+PFNGLGETNCONVOLUTIONFILTERPROC glGetnConvolutionFilter = nullptr;
+PFNGLGETNSEPARABLEFILTERPROC glGetnSeparableFilter = nullptr;
+PFNGLGETNHISTOGRAMPROC glGetnHistogram = nullptr;
+PFNGLGETNMINMAXPROC glGetnMinmax = nullptr;
+PFNGLTEXTUREBARRIERPROC glTextureBarrier = nullptr;
+
+// GL_VERSION_4_6
+PFNGLSPECIALIZESHADERPROC glSpecializeShader = nullptr;
+PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glMultiDrawArraysIndirectCount = nullptr;
+PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glMultiDrawElementsIndirectCount = nullptr;
+PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp = nullptr;
-#if LL_LINUX_NV_GL_HEADERS
-// linux nvidia headers. these define these differently to mesa's. ugh.
-PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
-PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;
-PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = NULL;
-#endif // LL_LINUX_NV_GL_HEADERS
#endif
LLGLManager gGLManager;
@@ -410,42 +939,12 @@ LLGLManager gGLManager;
LLGLManager::LLGLManager() :
mInited(FALSE),
mIsDisabled(FALSE),
-
- mHasMultitexture(FALSE),
- mHasATIMemInfo(FALSE),
- mHasAMDAssociations(FALSE),
- mHasNVXMemInfo(FALSE),
- mNumTextureUnits(1),
- mHasMipMapGeneration(FALSE),
- mHasCompressedTextures(FALSE),
- mHasFramebufferObject(FALSE),
mMaxSamples(0),
- mHasBlendFuncSeparate(FALSE),
- mHasSync(FALSE),
- mHasVertexBufferObject(FALSE),
- mHasVertexArrayObject(FALSE),
- mHasMapBufferRange(FALSE),
- mHasFlushBufferRange(FALSE),
- mHasPBuffer(FALSE),
- mNumTextureImageUnits(0),
- mHasOcclusionQuery(FALSE),
- mHasTimerQuery(FALSE),
- mHasOcclusionQuery2(FALSE),
- mHasPointParameters(FALSE),
- mHasDrawBuffers(FALSE),
- mHasTextureRectangle(FALSE),
- mHasTextureMultisample(FALSE),
- mHasTransformFeedback(FALSE),
+ mNumTextureImageUnits(1),
mMaxSampleMaskWords(0),
mMaxColorTextureSamples(0),
mMaxDepthTextureSamples(0),
mMaxIntegerSamples(0),
-
- mHasAnisotropic(FALSE),
- mHasARBEnvCombine(FALSE),
- mHasCubeMap(FALSE),
- mHasDebugOutput(FALSE),
-
mIsAMD(FALSE),
mIsNVIDIA(FALSE),
mIsIntel(FALSE),
@@ -453,9 +952,6 @@ LLGLManager::LLGLManager() :
mIsMobileGF(FALSE),
#endif
mHasRequirements(TRUE),
-
- mHasSeparateSpecularColor(FALSE),
-
mDriverVersionMajor(1),
mDriverVersionMinor(0),
mDriverVersionRelease(0),
@@ -473,7 +969,6 @@ LLGLManager::LLGLManager() :
//---------------------------------------------------------------------
void LLGLManager::initWGL()
{
- mHasPBuffer = FALSE;
#if LL_WINDOWS && !LL_MESA_HEADLESS
if (!glh_init_extensions("WGL_ARB_pixel_format"))
{
@@ -512,10 +1007,6 @@ void LLGLManager::initWGL()
{
LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL;
}
-
- mHasPBuffer = ExtensionExists("WGL_ARB_pbuffer", gGLHExts.mSysExts) &&
- ExtensionExists("WGL_ARB_render_texture", gGLHExts.mSysExts) &&
- ExtensionExists("WGL_ARB_pixel_format", gGLHExts.mSysExts);
#endif
}
@@ -529,7 +1020,7 @@ bool LLGLManager::initGL()
stop_glerror();
-#if LL_WINDOWS
+#if 0 && LL_WINDOWS
if (!glGetStringi)
{
glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
@@ -586,12 +1077,14 @@ bool LLGLManager::initGL()
{
parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor);
-#if LL_DARWIN
+#if 0 && LL_DARWIN
+ // TODO maybe switch to using a core profile for GL 3.2?
+ // https://stackoverflow.com/a/19868861
//never use GLSL greater than 1.20 on OSX
- if (mGLSLVersionMajor > 1 || mGLSLVersionMinor >= 30)
+ if (mGLSLVersionMajor > 1 || mGLSLVersionMinor > 30)
{
mGLSLVersionMajor = 1;
- mGLSLVersionMinor = 20;
+ mGLSLVersionMinor = 30;
}
#endif
}
@@ -674,23 +1167,6 @@ bool LLGLManager::initGL()
}
#endif
- if (mHasATIMemInfo && mVRAM == 0)
- { //ask the gl how much vram is free at startup and attempt to use no more than half of that
- S32 meminfo[4];
- glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
-
- mVRAM = meminfo[0] / 1024;
- LL_WARNS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL;
- }
-
- if (mHasNVXMemInfo && mVRAM == 0)
- {
- S32 dedicated_memory;
- glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);
- mVRAM = dedicated_memory/1024;
- LL_WARNS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL;
- }
-
#if LL_WINDOWS
if (mVRAM < 256)
{
@@ -718,66 +1194,26 @@ bool LLGLManager::initGL()
stop_glerror();
- GLint num_tex_image_units;
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
- mNumTextureImageUnits = llmin(num_tex_image_units, 32);
-
- if (mHasMultitexture)
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits);
+ stop_glerror();
+ glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples);
+ stop_glerror();
+ glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples);
+ stop_glerror();
+ glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples);
+ stop_glerror();
+ glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
+ stop_glerror();
+ glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
+ stop_glerror();
+
+ if (mGLVersion >= 4.59f)
{
- if (LLRender::sGLCoreProfile)
- {
- mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS);
- }
- else
- {
- GLint num_tex_units;
- glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
- mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS);
- if (mIsIntel)
- {
- mNumTextureUnits = llmin(mNumTextureUnits, 2);
- }
- }
+ glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxAnisotropy);
+ stop_glerror();
}
- else
- {
- mHasRequirements = FALSE;
-
- // We don't support cards that don't support the GL_ARB_multitexture extension
- LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL;
- return false;
- }
-
- stop_glerror();
-
- if (mHasTextureMultisample)
- {
- glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples);
- glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples);
- glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples);
- glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
- }
- stop_glerror();
-
- //HACK always disable texture multisample, use FXAA instead
- mHasTextureMultisample = FALSE;
-#if LL_WINDOWS
- if (mIsIntel && mGLVersion <= 3.f)
- { //never try to use framebuffer objects on older intel drivers (crashy)
- mHasFramebufferObject = FALSE;
- }
-#endif
-
- if (mHasFramebufferObject)
- {
- glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
- }
-
- stop_glerror();
-
initGLStates();
-
stop_glerror();
return true;
@@ -881,62 +1317,22 @@ void LLGLManager::asLLSD(LLSD& info)
info["vram"] = mVRAM;
- // Extensions used by everyone
- info["has_multitexture"] = mHasMultitexture;
- info["has_ati_mem_info"] = mHasATIMemInfo;
- info["has_nvx_mem_info"] = mHasNVXMemInfo;
- info["num_texture_units"] = mNumTextureUnits;
- info["has_mip_map_generation"] = mHasMipMapGeneration;
- info["has_compressed_textures"] = mHasCompressedTextures;
- info["has_framebuffer_object"] = mHasFramebufferObject;
+ // OpenGL limits
info["max_samples"] = mMaxSamples;
- info["has_blend_func_separate"] = mHasBlendFuncSeparate;
-
- // ARB Extensions
- info["has_vertex_buffer_object"] = mHasVertexBufferObject;
- info["has_vertex_array_object"] = mHasVertexArrayObject;
- info["has_sync"] = mHasSync;
- info["has_map_buffer_range"] = mHasMapBufferRange;
- info["has_flush_buffer_range"] = mHasFlushBufferRange;
- info["has_pbuffer"] = mHasPBuffer;
- info["has_shader_objects"] = std::string("Assumed TRUE"); // was mHasShaderObjects;
- info["has_vertex_shader"] = std::string("Assumed TRUE"); // was mHasVertexShader;
- info["has_fragment_shader"] = std::string("Assumed TRUE"); // was mHasFragmentShader;
info["num_texture_image_units"] = mNumTextureImageUnits;
- info["has_occlusion_query"] = mHasOcclusionQuery;
- info["has_timer_query"] = mHasTimerQuery;
- info["has_occlusion_query2"] = mHasOcclusionQuery2;
- info["has_point_parameters"] = mHasPointParameters;
- info["has_draw_buffers"] = mHasDrawBuffers;
- info["has_depth_clamp"] = mHasDepthClamp;
- info["has_texture_rectangle"] = mHasTextureRectangle;
- info["has_texture_multisample"] = mHasTextureMultisample;
- info["has_transform_feedback"] = mHasTransformFeedback;
info["max_sample_mask_words"] = mMaxSampleMaskWords;
info["max_color_texture_samples"] = mMaxColorTextureSamples;
info["max_depth_texture_samples"] = mMaxDepthTextureSamples;
info["max_integer_samples"] = mMaxIntegerSamples;
+ info["max_vertex_range"] = mGLMaxVertexRange;
+ info["max_index_range"] = mGLMaxIndexRange;
+ info["max_texture_size"] = mGLMaxTextureSize;
- // Other extensions.
- info["has_anisotropic"] = mHasAnisotropic;
- info["has_arb_env_combine"] = mHasARBEnvCombine;
- info["has_cube_map"] = mHasCubeMap;
- info["has_debug_output"] = mHasDebugOutput;
- info["has_srgb_texture"] = mHassRGBTexture;
- info["has_srgb_framebuffer"] = mHassRGBFramebuffer;
- info["has_texture_srgb_decode"] = mHasTexturesRGBDecode;
-
- // Vendor-specific extensions
+ // Which vendor
info["is_ati"] = mIsAMD; // note, do not rename is_ati to is_amd without coordinating with DW
info["is_nvidia"] = mIsNVIDIA;
info["is_intel"] = mIsIntel;
- // Other fields
- info["has_requirements"] = mHasRequirements;
- info["has_separate_specular_color"] = mHasSeparateSpecularColor;
- info["max_vertex_range"] = mGLMaxVertexRange;
- info["max_index_range"] = mGLMaxIndexRange;
- info["max_texture_size"] = mGLMaxTextureSize;
info["gl_renderer"] = mGLRenderer;
}
@@ -955,498 +1351,876 @@ void LLGLManager::shutdownGL()
void LLGLManager::initExtensions()
{
-#if LL_MESA_HEADLESS
-# ifdef GL_ARB_multitexture
- mHasMultitexture = TRUE;
-# else
- mHasMultitexture = FALSE;
-# endif // GL_ARB_multitexture
-# ifdef GL_ARB_texture_env_combine
- mHasARBEnvCombine = TRUE;
-# else
- mHasARBEnvCombine = FALSE;
-# endif // GL_ARB_texture_env_combine
-# ifdef GL_ARB_texture_compression
- mHasCompressedTextures = TRUE;
-# else
- mHasCompressedTextures = FALSE;
-# endif // GL_ARB_texture_compression
-# ifdef GL_ARB_vertex_buffer_object
- mHasVertexBufferObject = TRUE;
-# else
- mHasVertexBufferObject = FALSE;
-# endif // GL_ARB_vertex_buffer_object
-# ifdef GL_EXT_framebuffer_object
- mHasFramebufferObject = TRUE;
-# else
- mHasFramebufferObject = FALSE;
-# endif // GL_EXT_framebuffer_object
-# ifdef GL_ARB_draw_buffers
- mHasDrawBuffers = TRUE;
-#else
- mHasDrawBuffers = FALSE;
-# endif // GL_ARB_draw_buffers
-# if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp)
- mHasDepthClamp = TRUE;
-#else
- mHasDepthClamp = FALSE;
-#endif // defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp)
-# if GL_EXT_blend_func_separate
- mHasBlendFuncSeparate = TRUE;
-#else
- mHasBlendFuncSeparate = FALSE;
-# endif // GL_EXT_blend_func_separate
- mHasMipMapGeneration = FALSE;
- mHasSeparateSpecularColor = FALSE;
- mHasAnisotropic = FALSE;
- mHasCubeMap = FALSE;
- mHasOcclusionQuery = FALSE;
- mHasPointParameters = FALSE;
- mHasTextureRectangle = FALSE;
-#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
- mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
- mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations
- mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
- mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
- mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
- glh_init_extensions("GL_ARB_texture_cube_map");
- mHasCubeMap = ExtensionExists("GL_ARB_texture_cube_map", gGLHExts.mSysExts);
- mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
- mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
- mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
- mHasTimerQuery = ExtensionExists("GL_ARB_timer_query", gGLHExts.mSysExts);
- mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
- mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
- mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
- mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
- mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
- mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
- // NOTE: Using extensions breaks reflections when Shadows are set to projector. See: SL-16727
- //mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
- mHasDepthClamp = FALSE;
- // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
-#ifdef GL_ARB_framebuffer_object
- mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
-#else
- mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts) &&
- ExtensionExists("GL_EXT_framebuffer_blit", gGLHExts.mSysExts) &&
- ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) &&
- ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
-#endif
-#ifdef GL_EXT_texture_sRGB
- mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts);
-#endif
-
-#ifdef GL_ARB_framebuffer_sRGB
- mHassRGBFramebuffer = ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts);
-#else
- mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts);
-#endif
-
-#ifdef GL_EXT_texture_sRGB_decode
- mHasTexturesRGBDecode = ExtensionExists("GL_EXT_texture_sRGB_decode", gGLHExts.mSysExts);
-#else
- mHasTexturesRGBDecode = ExtensionExists("GL_ARB_texture_sRGB_decode", gGLHExts.mSysExts);
-#endif
-
- mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
-
- mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
- mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
- mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
- mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
- mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
- mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;
-#if !LL_DARWIN
- mHasPointParameters = ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
-#endif
+#if LL_DARWIN
+ GLint num_extensions = 0;
+ std::string all_extensions{""};
+ glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
+ for(GLint i = 0; i < num_extensions; ++i) {
+ char const * extension = (char const *)glGetStringi(GL_EXTENSIONS, i);
+ all_extensions += extension;
+ all_extensions += ' ';
+ }
+ if (num_extensions)
+ {
+ all_extensions += "GL_ARB_multitexture GL_ARB_texture_cube_map GL_ARB_texture_compression "; // These are in 3.2 core, but not listed by OSX
+ gGLHExts.mSysExts = strdup(all_extensions.data());
+ }
#endif
-#if LL_LINUX
- LL_INFOS() << "initExtensions() checking shell variables to adjust features..." << LL_ENDL;
- // Our extension support for the Linux Client is very young with some
- // potential driver gotchas, so offer a semi-secret way to turn it off.
- if (getenv("LL_GL_NOEXT"))
- {
- //mHasMultitexture = FALSE; // NEEDED!
- mHasDepthClamp = FALSE;
- mHasARBEnvCombine = FALSE;
- mHasCompressedTextures = FALSE;
- mHasVertexBufferObject = FALSE;
- mHasFramebufferObject = FALSE;
- mHasDrawBuffers = FALSE;
- mHasBlendFuncSeparate = FALSE;
- mHasMipMapGeneration = FALSE;
- mHasSeparateSpecularColor = FALSE;
- mHasAnisotropic = FALSE;
- mHasCubeMap = FALSE;
- mHasOcclusionQuery = FALSE;
- mHasPointParameters = FALSE;
- LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL;
- }
- else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */
- {
- // This switch attempts to turn off all support for exotic
- // extensions which I believe correspond to fatal driver
- // bug reports. This should be the default until we get a
- // proper blacklist/whitelist on Linux.
- mHasMipMapGeneration = FALSE;
- mHasAnisotropic = FALSE;
- //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar
- //mHasOcclusionQuery = FALSE; // source of many ATI system hangs
- mHasBlendFuncSeparate = FALSE;
- LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;
- }
- if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */
- {
- // This lets advanced troubleshooters disable specific
- // GL extensions to isolate problems with their hardware.
- // SL-28126
- const char *const blacklist = getenv("LL_GL_BLACKLIST"); /* Flawfinder: ignore */
- LL_WARNS("RenderInit") << "GL extension support partially disabled via LL_GL_BLACKLIST: " << blacklist << LL_ENDL;
- if (strchr(blacklist,'a')) mHasARBEnvCombine = FALSE;
- if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE;
- if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE;
- if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S
-// if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S
-// if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S
- if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE;
- if (strchr(blacklist,'i')) mHasAnisotropic = FALSE;//S
- if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S
-// if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S
- if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE;
- if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S
- if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
- if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
- if (strchr(blacklist,'s')) mHasTextureRectangle = FALSE;
- if (strchr(blacklist,'t')) mHasBlendFuncSeparate = FALSE;//S
- if (strchr(blacklist,'u')) mHasDepthClamp = FALSE;
-
- }
-#endif // LL_LINUX
-
- if (!mHasMultitexture)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize multitexturing" << LL_ENDL;
- }
- if (!mHasMipMapGeneration)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize mipmap generation" << LL_ENDL;
- }
- if (!mHasARBEnvCombine)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL;
- }
- if (!mHasSeparateSpecularColor)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL;
- }
- if (!mHasAnisotropic)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize anisotropic filtering" << LL_ENDL;
- }
- if (!mHasCompressedTextures)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_compression" << LL_ENDL;
- }
- if (!mHasOcclusionQuery)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL;
- }
- if (!mHasOcclusionQuery2)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL;
- }
- if (!mHasPointParameters)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL;
- }
- if (!mHasBlendFuncSeparate)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL;
- }
- if (!mHasDrawBuffers)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL;
- }
-
- // Disable certain things due to known bugs
- if (mIsIntel && mHasMipMapGeneration)
- {
- LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL;
- mHasMipMapGeneration = FALSE;
- }
+ // NOTE: version checks against mGLVersion should bias down by 0.01 because of F32 errors
+
+ // OpenGL 4.x capabilities
+ mHasCubeMapArray = mGLVersion >= 3.99f;
+ mHasTransformFeedback = mGLVersion >= 3.99f;
+ mHasDebugOutput = mGLVersion >= 4.29f;
- // Misc
+ // Misc
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
+ mInited = TRUE;
+
#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
- if (mHasVertexBufferObject)
- {
- glBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferARB");
- if (glBindBufferARB)
- {
- glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteBuffersARB");
- glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenBuffersARB");
- glIsBufferARB = (PFNGLISBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsBufferARB");
- glBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferDataARB");
- glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferSubDataARB");
- glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferSubDataARB");
- glMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBufferARB");
- glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapBufferARB");
- glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameterivARB");
- glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferPointervARB");
- }
- else
- {
- mHasVertexBufferObject = FALSE;
- }
- }
- if (mHasVertexArrayObject)
- {
- glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glBindVertexArray");
- glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteVertexArrays");
- glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenVertexArrays");
- glIsVertexArray = (PFNGLISVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glIsVertexArray");
- }
- if (mHasSync)
- {
- glFenceSync = (PFNGLFENCESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
- glIsSync = (PFNGLISSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glIsSync");
- glDeleteSync = (PFNGLDELETESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteSync");
- glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glClientWaitSync");
- glWaitSync = (PFNGLWAITSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glWaitSync");
- glGetInteger64v = (PFNGLGETINTEGER64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInteger64v");
- glGetSynciv = (PFNGLGETSYNCIVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetSynciv");
- }
- if (mHasMapBufferRange)
- {
- glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange");
- glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glFlushMappedBufferRange");
- }
- if (mHasFramebufferObject)
- {
- LL_INFOS() << "initExtensions() FramebufferObject-related procs..." << LL_ENDL;
- glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glIsRenderbuffer");
- glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glBindRenderbuffer");
- glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteRenderbuffers");
- glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenRenderbuffers");
- glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorage");
- glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetRenderbufferParameteriv");
- glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glIsFramebuffer");
- glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glBindFramebuffer");
- glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteFramebuffers");
- glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenFramebuffers");
- glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) GLH_EXT_GET_PROC_ADDRESS("glCheckFramebufferStatus");
- glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture1D");
- glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture2D");
- glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture3D");
- glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbuffer");
- glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameteriv");
- glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmap");
- glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glBlitFramebuffer");
- glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisample");
- glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTextureLayer");
- }
- if (mHasDrawBuffers)
- {
- glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB");
- }
- if (mHasBlendFuncSeparate)
- {
- glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");
- }
- if (mHasTextureMultisample)
- {
- glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample");
- glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
- glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
- glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
- }
- if (mHasTransformFeedback)
- {
- glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback");
- glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
- glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
- glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
- glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferBase");
- }
- if (mHasDebugOutput)
- {
- glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
- glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageInsertARB");
- glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallbackARB");
- glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLogARB");
- }
-#if (!LL_LINUX) || LL_LINUX_NV_GL_HEADERS
- // This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
- glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
- if (!glDrawRangeElements)
- {
- mGLMaxVertexRange = 0;
- mGLMaxIndexRange = 0;
- }
-#endif // !LL_LINUX || LL_LINUX_NV_GL_HEADERS
-#if LL_LINUX_NV_GL_HEADERS
- // nvidia headers are critically different from mesa-esque
- glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveTextureARB");
- glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glClientActiveTextureARB");
-#endif // LL_LINUX_NV_GL_HEADERS
-
- if (mHasOcclusionQuery)
- {
- LL_INFOS() << "initExtensions() OcclusionQuery-related procs..." << LL_ENDL;
- glGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueriesARB");
- glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteQueriesARB");
- glIsQueryARB = (PFNGLISQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsQueryARB");
- glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQueryARB");
- glEndQueryARB = (PFNGLENDQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQueryARB");
- glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryivARB");
- glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
- glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
- }
- if (mHasTimerQuery)
- {
- LL_INFOS() << "initExtensions() TimerQuery-related procs..." << LL_ENDL;
- glQueryCounter = (PFNGLQUERYCOUNTERPROC) GLH_EXT_GET_PROC_ADDRESS("glQueryCounter");
- glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjecti64v");
- glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64v");
- }
- if (mHasPointParameters)
- {
- LL_INFOS() << "initExtensions() PointParameters-related procs..." << LL_ENDL;
- glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfARB");
- glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfvARB");
- }
-
- // Assume shader capabilities
- glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB");
- glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB");
- glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB");
- glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB");
- glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB");
- glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB");
- glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB");
- glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB");
- glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB");
- glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB");
- glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB");
- glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB");
- glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB");
- glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB");
- glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB");
- glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB");
- glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB");
- glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB");
- glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB");
- glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB");
- glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB");
- glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB");
- glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB");
- glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB");
- glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB");
- glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB");
- glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB");
- glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB");
- glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB");
- glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv");
- glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB");
- glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB");
- glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB");
- glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB");
- glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB");
- glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB");
- glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB");
- glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB");
- glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB");
- glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB");
-
- LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL;
-
- // nSight doesn't support use of ARB funcs that have been normalized in the API
- if (!LLRender::sNsightDebugSupport)
+
+#if LL_WINDOWS
+ // WGL_AMD_gpu_association
+ wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
+ wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
+ wglGetContextGPUIDAMD = (PFNWGLGETCONTEXTGPUIDAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetContextGPUIDAMD");
+ wglCreateAssociatedContextAMD = (PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateAssociatedContextAMD");
+ wglCreateAssociatedContextAttribsAMD = (PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateAssociatedContextAttribsAMD");
+ wglDeleteAssociatedContextAMD = (PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglDeleteAssociatedContextAMD");
+ wglMakeAssociatedContextCurrentAMD = (PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglMakeAssociatedContextCurrentAMD");
+ wglGetCurrentAssociatedContextAMD = (PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetCurrentAssociatedContextAMD");
+ wglBlitContextFramebufferAMD = (PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglBlitContextFramebufferAMD");
+
+ // WGL_EXT_swap_control
+ wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
+ wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetSwapIntervalEXT");
+
+ // WGL_ARB_create_context
+ wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
+#endif
+
+
+ // Load entire OpenGL API through GetProcAddress, leaving sections beyond mGLVersion unloaded
+
+ // GL_VERSION_1_2
+ if (mGLVersion < 1.19f)
{
- glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
- glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
+ return;
}
- else
+ glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
+ glTexImage3D = (PFNGLTEXIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexImage3D");
+ glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexSubImage3D");
+ glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTexSubImage3D");
+
+
+ // GL_VERSION_1_3
+ if (mGLVersion < 1.29f)
{
- glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation");
- glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation");
+ return;
}
-
- glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB");
- glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
- glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
- glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB");
- glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB");
- glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB");
- glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB");
- glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB");
- glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB");
- glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB");
- glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB");
- glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB");
- glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB");
- glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB");
- glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB");
- glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB");
- glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB");
- glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB");
- glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB");
- glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB");
- glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB");
- glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB");
- glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB");
- glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB");
- glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB");
- glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB");
- glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB");
- glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB");
- glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB");
- glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB");
- glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB");
- glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB");
- glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB");
- glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB");
- glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB");
- glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
- glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
- glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
- glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");
- glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
- glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
- glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
- glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
- glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
- glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
- glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
- glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
- glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
- glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
- glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
- glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
- glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
- glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
- glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
- glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
- glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB");
- glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB");
- glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB");
- glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");
- glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB");
- glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB");
- glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB");
- glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB");
- glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
-
- LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL;
+ glActiveTexture = (PFNGLACTIVETEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveTexture");
+ glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glSampleCoverage");
+ glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage3D");
+ glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage2D");
+ glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexImage1D");
+ glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage3D");
+ glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage2D");
+ glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTexSubImage1D");
+ glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCompressedTexImage");
+ glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glClientActiveTexture");
+ glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1d");
+ glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1dv");
+ glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1f");
+ glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1fv");
+ glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1i");
+ glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1iv");
+ glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1s");
+ glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord1sv");
+ glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2d");
+ glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2dv");
+ glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2f");
+ glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2fv");
+ glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2i");
+ glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2iv");
+ glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2s");
+ glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord2sv");
+ glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3d");
+ glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3dv");
+ glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3f");
+ glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3fv");
+ glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3i");
+ glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3iv");
+ glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3s");
+ glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord3sv");
+ glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4d");
+ glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4dv");
+ glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4f");
+ glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4fv");
+ glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4i");
+ glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4iv");
+ glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4s");
+ glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoord4sv");
+ glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)GLH_EXT_GET_PROC_ADDRESS("glLoadTransposeMatrixf");
+ glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)GLH_EXT_GET_PROC_ADDRESS("glLoadTransposeMatrixd");
+ glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)GLH_EXT_GET_PROC_ADDRESS("glMultTransposeMatrixf");
+ glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)GLH_EXT_GET_PROC_ADDRESS("glMultTransposeMatrixd");
+
+ // GL_VERSION_1_4
+ if (mGLVersion < 1.39f)
+ {
+ return;
+ }
+ glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparate");
+ glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawArrays");
+ glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElements");
+ glPointParameterf = (PFNGLPOINTPARAMETERFPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterf");
+ glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfv");
+ glPointParameteri = (PFNGLPOINTPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameteri");
+ glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameteriv");
+ glFogCoordf = (PFNGLFOGCOORDFPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordf");
+ glFogCoordfv = (PFNGLFOGCOORDFVPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordfv");
+ glFogCoordd = (PFNGLFOGCOORDDPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordd");
+ glFogCoorddv = (PFNGLFOGCOORDDVPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoorddv");
+ glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glFogCoordPointer");
+ glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3b");
+ glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3bv");
+ glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3d");
+ glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3dv");
+ glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3f");
+ glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3fv");
+ glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3i");
+ glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3iv");
+ glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3s");
+ glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3sv");
+ glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ub");
+ glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ubv");
+ glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3ui");
+ glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3uiv");
+ glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3us");
+ glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColor3usv");
+ glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColorPointer");
+ glWindowPos2d = (PFNGLWINDOWPOS2DPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2d");
+ glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2dv");
+ glWindowPos2f = (PFNGLWINDOWPOS2FPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2f");
+ glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2fv");
+ glWindowPos2i = (PFNGLWINDOWPOS2IPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2i");
+ glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2iv");
+ glWindowPos2s = (PFNGLWINDOWPOS2SPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2s");
+ glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos2sv");
+ glWindowPos3d = (PFNGLWINDOWPOS3DPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3d");
+ glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3dv");
+ glWindowPos3f = (PFNGLWINDOWPOS3FPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3f");
+ glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3fv");
+ glWindowPos3i = (PFNGLWINDOWPOS3IPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3i");
+ glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3iv");
+ glWindowPos3s = (PFNGLWINDOWPOS3SPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3s");
+ glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)GLH_EXT_GET_PROC_ADDRESS("glWindowPos3sv");
+
+ // GL_VERSION_1_5
+ if (mGLVersion < 1.49f)
+ {
+ return;
+ }
+ glGenQueries = (PFNGLGENQUERIESPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueries");
+ glDeleteQueries = (PFNGLDELETEQUERIESPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteQueries");
+ glIsQuery = (PFNGLISQUERYPROC)GLH_EXT_GET_PROC_ADDRESS("glIsQuery");
+ glBeginQuery = (PFNGLBEGINQUERYPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQuery");
+ glEndQuery = (PFNGLENDQUERYPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQuery");
+ glGetQueryiv = (PFNGLGETQUERYIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryiv");
+ glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectiv");
+ glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuiv");
+ glBindBuffer = (PFNGLBINDBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBuffer");
+ glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteBuffers");
+ glGenBuffers = (PFNGLGENBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenBuffers");
+ glIsBuffer = (PFNGLISBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsBuffer");
+ glBufferData = (PFNGLBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferData");
+ glBufferSubData = (PFNGLBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferSubData");
+ glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferSubData");
+ glMapBuffer = (PFNGLMAPBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBuffer");
+ glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapBuffer");
+ glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameteriv");
+ glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferPointerv");
+
+ // GL_VERSION_2_0
+ if (mGLVersion < 1.9f)
+ {
+ return;
+ }
+ glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendEquationSeparate");
+ glDrawBuffers = (PFNGLDRAWBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawBuffers");
+ glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glStencilOpSeparate");
+ glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glStencilFuncSeparate");
+ glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)GLH_EXT_GET_PROC_ADDRESS("glStencilMaskSeparate");
+ glAttachShader = (PFNGLATTACHSHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glAttachShader");
+ glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation");
+ glCompileShader = (PFNGLCOMPILESHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glCompileShader");
+ glCreateProgram = (PFNGLCREATEPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateProgram");
+ glCreateShader = (PFNGLCREATESHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateShader");
+ glDeleteProgram = (PFNGLDELETEPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteProgram");
+ glDeleteShader = (PFNGLDELETESHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteShader");
+ glDetachShader = (PFNGLDETACHSHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glDetachShader");
+ glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArray");
+ glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArray");
+ glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttrib");
+ glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniform");
+ glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGetAttachedShaders");
+ glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation");
+ glGetProgramiv = (PFNGLGETPROGRAMIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramiv");
+ glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramInfoLog");
+ glGetShaderiv = (PFNGLGETSHADERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetShaderiv");
+ glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetShaderInfoLog");
+ glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetShaderSource");
+ glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocation");
+ glGetUniformfv = (PFNGLGETUNIFORMFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformfv");
+ glGetUniformiv = (PFNGLGETUNIFORMIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformiv");
+ glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdv");
+ glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfv");
+ glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribiv");
+ glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribPointerv");
+ glIsProgram = (PFNGLISPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glIsProgram");
+ glIsShader = (PFNGLISSHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsShader");
+ glLinkProgram = (PFNGLLINKPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glLinkProgram");
+ glShaderSource = (PFNGLSHADERSOURCEPROC)GLH_EXT_GET_PROC_ADDRESS("glShaderSource");
+ glUseProgram = (PFNGLUSEPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glUseProgram");
+ glUniform1f = (PFNGLUNIFORM1FPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1f");
+ glUniform2f = (PFNGLUNIFORM2FPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2f");
+ glUniform3f = (PFNGLUNIFORM3FPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3f");
+ glUniform4f = (PFNGLUNIFORM4FPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4f");
+ glUniform1i = (PFNGLUNIFORM1IPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1i");
+ glUniform2i = (PFNGLUNIFORM2IPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2i");
+ glUniform3i = (PFNGLUNIFORM3IPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3i");
+ glUniform4i = (PFNGLUNIFORM4IPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4i");
+ glUniform1fv = (PFNGLUNIFORM1FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1fv");
+ glUniform2fv = (PFNGLUNIFORM2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2fv");
+ glUniform3fv = (PFNGLUNIFORM3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3fv");
+ glUniform4fv = (PFNGLUNIFORM4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4fv");
+ glUniform1iv = (PFNGLUNIFORM1IVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1iv");
+ glUniform2iv = (PFNGLUNIFORM2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2iv");
+ glUniform3iv = (PFNGLUNIFORM3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3iv");
+ glUniform4iv = (PFNGLUNIFORM4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4iv");
+ glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fv");
+ glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fv");
+ glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fv");
+ glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glValidateProgram");
+ glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1d");
+ glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dv");
+ glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1f");
+ glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fv");
+ glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1s");
+ glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sv");
+ glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2d");
+ glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dv");
+ glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2f");
+ glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fv");
+ glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2s");
+ glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sv");
+ glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3d");
+ glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dv");
+ glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3f");
+ glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fv");
+ glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3s");
+ glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sv");
+ glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nbv");
+ glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Niv");
+ glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nsv");
+ glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nub");
+ glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nubv");
+ glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nuiv");
+ glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4Nusv");
+ glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bv");
+ glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4d");
+ glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dv");
+ glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4f");
+ glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fv");
+ glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4iv");
+ glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4s");
+ glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sv");
+ glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubv");
+ glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uiv");
+ glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usv");
+ glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointer");
+
+ // GL_VERSION_2_1
+ if (mGLVersion < 2.09f)
+ {
+ return;
+ }
+ glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2x3fv");
+ glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x2fv");
+ glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2x4fv");
+ glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4x2fv");
+ glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv");
+ glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4x3fv");
+
+ // GL_VERSION_3_0
+ if (mGLVersion < 2.99f)
+ {
+ return;
+ }
+ glColorMaski = (PFNGLCOLORMASKIPROC)GLH_EXT_GET_PROC_ADDRESS("glColorMaski");
+ glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBooleani_v");
+ glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetIntegeri_v");
+ glEnablei = (PFNGLENABLEIPROC)GLH_EXT_GET_PROC_ADDRESS("glEnablei");
+ glDisablei = (PFNGLDISABLEIPROC)GLH_EXT_GET_PROC_ADDRESS("glDisablei");
+ glIsEnabledi = (PFNGLISENABLEDIPROC)GLH_EXT_GET_PROC_ADDRESS("glIsEnabledi");
+ glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback");
+ glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
+ glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
+ glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferBase");
+ glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
+ glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTransformFeedbackVarying");
+ glClampColor = (PFNGLCLAMPCOLORPROC)GLH_EXT_GET_PROC_ADDRESS("glClampColor");
+ glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginConditionalRender");
+ glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)GLH_EXT_GET_PROC_ADDRESS("glEndConditionalRender");
+ glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");
+ glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribIiv");
+ glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribIuiv");
+ glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI1i");
+ glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI2i");
+ glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI3i");
+ glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4i");
+ glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI1ui");
+ glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI2ui");
+ glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI3ui");
+ glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4ui");
+ glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI1iv");
+ glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI2iv");
+ glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI3iv");
+ glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4iv");
+ glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI1uiv");
+ glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI2uiv");
+ glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI3uiv");
+ glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4uiv");
+ glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4bv");
+ glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4sv");
+ glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4ubv");
+ glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribI4usv");
+ glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformuiv");
+ glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glBindFragDataLocation");
+ glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFragDataLocation");
+ glUniform1ui = (PFNGLUNIFORM1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1ui");
+ glUniform2ui = (PFNGLUNIFORM2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2ui");
+ glUniform3ui = (PFNGLUNIFORM3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3ui");
+ glUniform4ui = (PFNGLUNIFORM4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4ui");
+ glUniform1uiv = (PFNGLUNIFORM1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1uiv");
+ glUniform2uiv = (PFNGLUNIFORM2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2uiv");
+ glUniform3uiv = (PFNGLUNIFORM3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3uiv");
+ glUniform4uiv = (PFNGLUNIFORM4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4uiv");
+ glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexParameterIiv");
+ glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexParameterIuiv");
+ glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTexParameterIiv");
+ glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTexParameterIuiv");
+ glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferiv");
+ glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferuiv");
+ glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferfv");
+ glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferfi");
+ glGetStringi = (PFNGLGETSTRINGIPROC)GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
+ glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsRenderbuffer");
+ glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindRenderbuffer");
+ glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteRenderbuffers");
+ glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenRenderbuffers");
+ glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorage");
+ glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetRenderbufferParameteriv");
+ glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsFramebuffer");
+ glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindFramebuffer");
+ glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteFramebuffers");
+ glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenFramebuffers");
+ glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)GLH_EXT_GET_PROC_ADDRESS("glCheckFramebufferStatus");
+ glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture1D");
+ glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture2D");
+ glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture3D");
+ glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbuffer");
+ glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameteriv");
+ glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmap");
+ glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBlitFramebuffer");
+ glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisample");
+ glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTextureLayer");
+ glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange");
+ glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glFlushMappedBufferRange");
+ glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)GLH_EXT_GET_PROC_ADDRESS("glBindVertexArray");
+ glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteVertexArrays");
+ glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenVertexArrays");
+ glIsVertexArray = (PFNGLISVERTEXARRAYPROC)GLH_EXT_GET_PROC_ADDRESS("glIsVertexArray");
+
+ // GL_VERSION_3_1
+ if (mGLVersion < 3.09f)
+ {
+ return;
+ }
+ glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawArraysInstanced");
+ glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsInstanced");
+ glTexBuffer = (PFNGLTEXBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glTexBuffer");
+ glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glPrimitiveRestartIndex");
+ glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyBufferSubData");
+ glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformIndices");
+ glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformsiv");
+ glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformName");
+ glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformBlockIndex");
+ glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformBlockiv");
+ glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformBlockName");
+ glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformBlockBinding");
+
+ // GL_VERSION_3_2
+ if (mGLVersion < 3.19f)
+ {
+ return;
+ }
+ glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsBaseVertex");
+ glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElementsBaseVertex");
+ glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsInstancedBaseVertex");
+ glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElementsBaseVertex");
+ glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)GLH_EXT_GET_PROC_ADDRESS("glProvokingVertex");
+ glFenceSync = (PFNGLFENCESYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
+ glIsSync = (PFNGLISSYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glIsSync");
+ glDeleteSync = (PFNGLDELETESYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteSync");
+ glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glClientWaitSync");
+ glWaitSync = (PFNGLWAITSYNCPROC)GLH_EXT_GET_PROC_ADDRESS("glWaitSync");
+ glGetInteger64v = (PFNGLGETINTEGER64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetInteger64v");
+ glGetSynciv = (PFNGLGETSYNCIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSynciv");
+ glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetInteger64i_v");
+ glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameteri64v");
+ glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture");
+ glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample");
+ glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
+ glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
+ glSampleMaski = (PFNGLSAMPLEMASKIPROC)GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
+
+ // GL_VERSION_3_3
+ if (mGLVersion < 3.29f)
+ {
+ return;
+ }
+ glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glBindFragDataLocationIndexed");
+ glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFragDataIndex");
+ glGenSamplers = (PFNGLGENSAMPLERSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenSamplers");
+ glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteSamplers");
+ glIsSampler = (PFNGLISSAMPLERPROC)GLH_EXT_GET_PROC_ADDRESS("glIsSampler");
+ glBindSampler = (PFNGLBINDSAMPLERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindSampler");
+ glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameteri");
+ glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameteriv");
+ glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameterf");
+ glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameterfv");
+ glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameterIiv");
+ glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSamplerParameterIuiv");
+ glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSamplerParameteriv");
+ glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSamplerParameterIiv");
+ glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSamplerParameterfv");
+ glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSamplerParameterIuiv");
+ glQueryCounter = (PFNGLQUERYCOUNTERPROC)GLH_EXT_GET_PROC_ADDRESS("glQueryCounter");
+ glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjecti64v");
+ glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64v");
+ glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribDivisor");
+ glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP1ui");
+ glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP1uiv");
+ glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP2ui");
+ glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP2uiv");
+ glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP3ui");
+ glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP3uiv");
+ glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP4ui");
+ glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribP4uiv");
+ glVertexP2ui = (PFNGLVERTEXP2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP2ui");
+ glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP2uiv");
+ glVertexP3ui = (PFNGLVERTEXP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP3ui");
+ glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP3uiv");
+ glVertexP4ui = (PFNGLVERTEXP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP4ui");
+ glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexP4uiv");
+ glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP1ui");
+ glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP1uiv");
+ glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP2ui");
+ glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP2uiv");
+ glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP3ui");
+ glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP3uiv");
+ glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP4ui");
+ glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTexCoordP4uiv");
+ glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP1ui");
+ glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP1uiv");
+ glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP2ui");
+ glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP2uiv");
+ glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP3ui");
+ glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP3uiv");
+ glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP4ui");
+ glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiTexCoordP4uiv");
+ glNormalP3ui = (PFNGLNORMALP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glNormalP3ui");
+ glNormalP3uiv = (PFNGLNORMALP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glNormalP3uiv");
+ glColorP3ui = (PFNGLCOLORP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glColorP3ui");
+ glColorP3uiv = (PFNGLCOLORP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glColorP3uiv");
+ glColorP4ui = (PFNGLCOLORP4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glColorP4ui");
+ glColorP4uiv = (PFNGLCOLORP4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glColorP4uiv");
+ glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColorP3ui");
+ glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glSecondaryColorP3uiv");
+
+ // GL_VERSION_4_0
+ if (mGLVersion < 3.99f)
+ {
+ return;
+ }
+ glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)GLH_EXT_GET_PROC_ADDRESS("glMinSampleShading");
+ glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendEquationi");
+ glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendEquationSeparatei");
+ glBlendFunci = (PFNGLBLENDFUNCIPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendFunci");
+ glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparatei");
+ glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawArraysIndirect");
+ glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsIndirect");
+ glUniform1d = (PFNGLUNIFORM1DPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1d");
+ glUniform2d = (PFNGLUNIFORM2DPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2d");
+ glUniform3d = (PFNGLUNIFORM3DPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3d");
+ glUniform4d = (PFNGLUNIFORM4DPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4d");
+ glUniform1dv = (PFNGLUNIFORM1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform1dv");
+ glUniform2dv = (PFNGLUNIFORM2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform2dv");
+ glUniform3dv = (PFNGLUNIFORM3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform3dv");
+ glUniform4dv = (PFNGLUNIFORM4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniform4dv");
+ glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2dv");
+ glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3dv");
+ glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4dv");
+ glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2x3dv");
+ glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2x4dv");
+ glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x2dv");
+ glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4dv");
+ glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4x2dv");
+ glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4x3dv");
+ glGetUniformdv = (PFNGLGETUNIFORMDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformdv");
+ glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSubroutineUniformLocation");
+ glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetSubroutineIndex");
+ glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveSubroutineUniformiv");
+ glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveSubroutineUniformName");
+ glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveSubroutineName");
+ glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glUniformSubroutinesuiv");
+ glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetUniformSubroutineuiv");
+ glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramStageiv");
+ glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glPatchParameteri");
+ glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glPatchParameterfv");
+ glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glBindTransformFeedback");
+ glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteTransformFeedbacks");
+ glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)GLH_EXT_GET_PROC_ADDRESS("glGenTransformFeedbacks");
+ glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glIsTransformFeedback");
+ glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glPauseTransformFeedback");
+ glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glResumeTransformFeedback");
+ glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawTransformFeedback");
+ glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawTransformFeedbackStream");
+ glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQueryIndexed");
+ glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQueryIndexed");
+ glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryIndexediv");
+
+ // GL_VERSION_4_1
+ if (mGLVersion < 4.09f)
+ {
+ return;
+ }
+ glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)GLH_EXT_GET_PROC_ADDRESS("glReleaseShaderCompiler");
+ glShaderBinary = (PFNGLSHADERBINARYPROC)GLH_EXT_GET_PROC_ADDRESS("glShaderBinary");
+ glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glGetShaderPrecisionFormat");
+ glDepthRangef = (PFNGLDEPTHRANGEFPROC)GLH_EXT_GET_PROC_ADDRESS("glDepthRangef");
+ glClearDepthf = (PFNGLCLEARDEPTHFPROC)GLH_EXT_GET_PROC_ADDRESS("glClearDepthf");
+ glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramBinary");
+ glProgramBinary = (PFNGLPROGRAMBINARYPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramBinary");
+ glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramParameteri");
+ glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)GLH_EXT_GET_PROC_ADDRESS("glUseProgramStages");
+ glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveShaderProgram");
+ glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateShaderProgramv");
+ glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindProgramPipeline");
+ glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramPipelines");
+ glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)GLH_EXT_GET_PROC_ADDRESS("glGenProgramPipelines");
+ glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)GLH_EXT_GET_PROC_ADDRESS("glIsProgramPipeline");
+ glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramPipelineiv");
+ glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1i");
+ glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1iv");
+ glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1f");
+ glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1fv");
+ glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1d");
+ glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1dv");
+ glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1ui");
+ glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform1uiv");
+ glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2i");
+ glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2iv");
+ glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2f");
+ glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2fv");
+ glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2d");
+ glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2dv");
+ glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2ui");
+ glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform2uiv");
+ glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3i");
+ glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3iv");
+ glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3f");
+ glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3fv");
+ glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3d");
+ glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3dv");
+ glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3ui");
+ glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform3uiv");
+ glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4i");
+ glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4iv");
+ glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4f");
+ glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4fv");
+ glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4d");
+ glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4dv");
+ glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4ui");
+ glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniform4uiv");
+ glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2fv");
+ glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3fv");
+ glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4fv");
+ glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2dv");
+ glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3dv");
+ glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4dv");
+ glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2x3fv");
+ glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3x2fv");
+ glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2x4fv");
+ glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4x2fv");
+ glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3x4fv");
+ glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4x3fv");
+ glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2x3dv");
+ glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3x2dv");
+ glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix2x4dv");
+ glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4x2dv");
+ glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix3x4dv");
+ glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glProgramUniformMatrix4x3dv");
+ glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)GLH_EXT_GET_PROC_ADDRESS("glValidateProgramPipeline");
+ glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramPipelineInfoLog");
+ glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL1d");
+ glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL2d");
+ glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL3d");
+ glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL4d");
+ glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL1dv");
+ glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL2dv");
+ glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL3dv");
+ glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribL4dv");
+ glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribLPointer");
+ glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribLdv");
+ glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)GLH_EXT_GET_PROC_ADDRESS("glViewportArrayv");
+ glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)GLH_EXT_GET_PROC_ADDRESS("glViewportIndexedf");
+ glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)GLH_EXT_GET_PROC_ADDRESS("glViewportIndexedfv");
+ glScissorArrayv = (PFNGLSCISSORARRAYVPROC)GLH_EXT_GET_PROC_ADDRESS("glScissorArrayv");
+ glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glScissorIndexed");
+ glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)GLH_EXT_GET_PROC_ADDRESS("glScissorIndexedv");
+ glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)GLH_EXT_GET_PROC_ADDRESS("glDepthRangeArrayv");
+ glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDepthRangeIndexed");
+ glGetFloati_v = (PFNGLGETFLOATI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFloati_v");
+ glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetDoublei_v");
+
+ // GL_VERSION_4_2
+ if (mGLVersion < 4.19f)
+ {
+ return;
+ }
+ glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawArraysInstancedBaseInstance");
+ glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsInstancedBaseInstance");
+ glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawElementsInstancedBaseVertexBaseInstance");
+ glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetInternalformativ");
+ glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetActiveAtomicCounterBufferiv");
+ glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glBindImageTexture");
+ glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)GLH_EXT_GET_PROC_ADDRESS("glMemoryBarrier");
+ glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage1D");
+ glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage2D");
+ glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage3D");
+ glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawTransformFeedbackInstanced");
+ glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawTransformFeedbackStreamInstanced");
+
+ // GL_VERSION_4_3
+ if (mGLVersion < 4.29f)
+ {
+ return;
+ }
+ glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferData");
+ glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glClearBufferSubData");
+ glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)GLH_EXT_GET_PROC_ADDRESS("glDispatchCompute");
+ glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glDispatchComputeIndirect");
+ glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyImageSubData");
+ glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glFramebufferParameteri");
+ glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferParameteriv");
+ glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetInternalformati64v");
+ glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateTexSubImage");
+ glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateTexImage");
+ glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateBufferSubData");
+ glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateBufferData");
+ glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateFramebuffer");
+ glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateSubFramebuffer");
+ glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawArraysIndirect");
+ glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElementsIndirect");
+ glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramInterfaceiv");
+ glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceIndex");
+ glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceName");
+ glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceiv");
+ glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceLocation");
+ glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetProgramResourceLocationIndex");
+ glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)GLH_EXT_GET_PROC_ADDRESS("glShaderStorageBlockBinding");
+ glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexBufferRange");
+ glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage2DMultisample");
+ glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTexStorage3DMultisample");
+ glTextureView = (PFNGLTEXTUREVIEWPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureView");
+ glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBindVertexBuffer");
+ glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribFormat");
+ glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIFormat");
+ glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribLFormat");
+ glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexAttribBinding");
+ glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexBindingDivisor");
+ glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControl");
+ glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)GLH_EXT_GET_PROC_ADDRESS("glDebugMessageInsert");
+ glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallback");
+ glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLog");
+ glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)GLH_EXT_GET_PROC_ADDRESS("glPushDebugGroup");
+ glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)GLH_EXT_GET_PROC_ADDRESS("glPopDebugGroup");
+ glObjectLabel = (PFNGLOBJECTLABELPROC)GLH_EXT_GET_PROC_ADDRESS("glObjectLabel");
+ glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)GLH_EXT_GET_PROC_ADDRESS("glGetObjectLabel");
+ glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)GLH_EXT_GET_PROC_ADDRESS("glObjectPtrLabel");
+ glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)GLH_EXT_GET_PROC_ADDRESS("glGetObjectPtrLabel");
+
+ // GL_VERSION_4_4
+ if (mGLVersion < 4.39f)
+ {
+ return;
+ }
+ glBufferStorage = (PFNGLBUFFERSTORAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferStorage");
+ glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glClearTexImage");
+ glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glClearTexSubImage");
+ glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBuffersBase");
+ glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBuffersRange");
+ glBindTextures = (PFNGLBINDTEXTURESPROC)GLH_EXT_GET_PROC_ADDRESS("glBindTextures");
+ glBindSamplers = (PFNGLBINDSAMPLERSPROC)GLH_EXT_GET_PROC_ADDRESS("glBindSamplers");
+ glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)GLH_EXT_GET_PROC_ADDRESS("glBindImageTextures");
+ glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glBindVertexBuffers");
+
+ // GL_VERSION_4_5
+ if (mGLVersion < 4.49f)
+ {
+ return;
+ }
+ glClipControl = (PFNGLCLIPCONTROLPROC)GLH_EXT_GET_PROC_ADDRESS("glClipControl");
+ glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateTransformFeedbacks");
+ glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackBufferBase");
+ glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackBufferRange");
+ glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTransformFeedbackiv");
+ glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTransformFeedbacki_v");
+ glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTransformFeedbacki64_v");
+ glCreateBuffers = (PFNGLCREATEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateBuffers");
+ glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedBufferStorage");
+ glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedBufferData");
+ glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedBufferSubData");
+ glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyNamedBufferSubData");
+ glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedBufferData");
+ glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedBufferSubData");
+ glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glMapNamedBuffer");
+ glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glMapNamedBufferRange");
+ glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapNamedBuffer");
+ glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glFlushMappedNamedBufferRange");
+ glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedBufferParameteriv");
+ glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedBufferParameteri64v");
+ glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedBufferPointerv");
+ glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedBufferSubData");
+ glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateFramebuffers");
+ glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferRenderbuffer");
+ glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferParameteri");
+ glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferTexture");
+ glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferTextureLayer");
+ glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferDrawBuffer");
+ glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferDrawBuffers");
+ glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedFramebufferReadBuffer");
+ glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateNamedFramebufferData");
+ glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)GLH_EXT_GET_PROC_ADDRESS("glInvalidateNamedFramebufferSubData");
+ glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedFramebufferiv");
+ glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedFramebufferuiv");
+ glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedFramebufferfv");
+ glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)GLH_EXT_GET_PROC_ADDRESS("glClearNamedFramebufferfi");
+ glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glBlitNamedFramebuffer");
+ glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)GLH_EXT_GET_PROC_ADDRESS("glCheckNamedFramebufferStatus");
+ glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedFramebufferParameteriv");
+ glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedFramebufferAttachmentParameteriv");
+ glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateRenderbuffers");
+ glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedRenderbufferStorage");
+ glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glNamedRenderbufferStorageMultisample");
+ glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetNamedRenderbufferParameteriv");
+ glCreateTextures = (PFNGLCREATETEXTURESPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateTextures");
+ glTextureBuffer = (PFNGLTEXTUREBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureBuffer");
+ glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureBufferRange");
+ glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage1D");
+ glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage2D");
+ glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage3D");
+ glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage2DMultisample");
+ glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureStorage3DMultisample");
+ glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureSubImage1D");
+ glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureSubImage2D");
+ glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureSubImage3D");
+ glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTextureSubImage1D");
+ glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTextureSubImage2D");
+ glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCompressedTextureSubImage3D");
+ glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTextureSubImage1D");
+ glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTextureSubImage2D");
+ glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC)GLH_EXT_GET_PROC_ADDRESS("glCopyTextureSubImage3D");
+ glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameterf");
+ glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameterfv");
+ glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameteri");
+ glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameterIiv");
+ glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameterIuiv");
+ glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureParameteriv");
+ glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)GLH_EXT_GET_PROC_ADDRESS("glGenerateTextureMipmap");
+ glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC)GLH_EXT_GET_PROC_ADDRESS("glBindTextureUnit");
+ glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureImage");
+ glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCompressedTextureImage");
+ glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureLevelParameterfv");
+ glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureLevelParameteriv");
+ glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureParameterfv");
+ glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureParameterIiv");
+ glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureParameterIuiv");
+ glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureParameteriv");
+ glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateVertexArrays");
+ glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC)GLH_EXT_GET_PROC_ADDRESS("glDisableVertexArrayAttrib");
+ glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC)GLH_EXT_GET_PROC_ADDRESS("glEnableVertexArrayAttrib");
+ glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayElementBuffer");
+ glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayVertexBuffer");
+ glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayVertexBuffers");
+ glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayAttribBinding");
+ glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayAttribFormat");
+ glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayAttribIFormat");
+ glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayAttribLFormat");
+ glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC)GLH_EXT_GET_PROC_ADDRESS("glVertexArrayBindingDivisor");
+ glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexArrayiv");
+ glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexArrayIndexediv");
+ glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetVertexArrayIndexed64iv");
+ glCreateSamplers = (PFNGLCREATESAMPLERSPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateSamplers");
+ glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateProgramPipelines");
+ glCreateQueries = (PFNGLCREATEQUERIESPROC)GLH_EXT_GET_PROC_ADDRESS("glCreateQueries");
+ glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryBufferObjecti64v");
+ glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryBufferObjectiv");
+ glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryBufferObjectui64v");
+ glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryBufferObjectuiv");
+ glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC)GLH_EXT_GET_PROC_ADDRESS("glMemoryBarrierByRegion");
+ glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetTextureSubImage");
+ glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetCompressedTextureSubImage");
+ glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC)GLH_EXT_GET_PROC_ADDRESS("glGetGraphicsResetStatus");
+ glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnCompressedTexImage");
+ glGetnTexImage = (PFNGLGETNTEXIMAGEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnTexImage");
+ glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnUniformdv");
+ glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnUniformfv");
+ glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnUniformiv");
+ glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnUniformuiv");
+ glReadnPixels = (PFNGLREADNPIXELSPROC)GLH_EXT_GET_PROC_ADDRESS("glReadnPixels");
+ glGetnMapdv = (PFNGLGETNMAPDVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnMapdv");
+ glGetnMapfv = (PFNGLGETNMAPFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnMapfv");
+ glGetnMapiv = (PFNGLGETNMAPIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnMapiv");
+ glGetnPixelMapfv = (PFNGLGETNPIXELMAPFVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnPixelMapfv");
+ glGetnPixelMapuiv = (PFNGLGETNPIXELMAPUIVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnPixelMapuiv");
+ glGetnPixelMapusv = (PFNGLGETNPIXELMAPUSVPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnPixelMapusv");
+ glGetnPolygonStipple = (PFNGLGETNPOLYGONSTIPPLEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnPolygonStipple");
+ glGetnColorTable = (PFNGLGETNCOLORTABLEPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnColorTable");
+ glGetnConvolutionFilter = (PFNGLGETNCONVOLUTIONFILTERPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnConvolutionFilter");
+ glGetnSeparableFilter = (PFNGLGETNSEPARABLEFILTERPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnSeparableFilter");
+ glGetnHistogram = (PFNGLGETNHISTOGRAMPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnHistogram");
+ glGetnMinmax = (PFNGLGETNMINMAXPROC)GLH_EXT_GET_PROC_ADDRESS("glGetnMinmax");
+ glTextureBarrier = (PFNGLTEXTUREBARRIERPROC)GLH_EXT_GET_PROC_ADDRESS("glTextureBarrier");
+
+ // GL_VERSION_4_6
+ if (mGLVersion < 4.59f)
+ {
+ return;
+ }
+ glSpecializeShader = (PFNGLSPECIALIZESHADERPROC)GLH_EXT_GET_PROC_ADDRESS("glSpecializeShader");
+ glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawArraysIndirectCount");
+ glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElementsIndirectCount");
+ glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)GLH_EXT_GET_PROC_ADDRESS("glPolygonOffsetClamp");
+
#endif
-
- mInited = TRUE;
}
void rotate_quat(LLQuaternion& rotation)
@@ -1584,8 +2358,8 @@ void LLGLState::initClass()
// sStateMap[GL_TEXTURE_2D] = GL_TRUE;
//make sure multisample defaults to disabled
- sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
- glDisable(GL_MULTISAMPLE_ARB);
+ sStateMap[GL_MULTISAMPLE] = GL_FALSE;
+ glDisable(GL_MULTISAMPLE);
}
//static
@@ -1606,7 +2380,7 @@ void LLGLState::resetTextureStates()
for (S32 j = maxTextureUnits-1; j >=0; j--)
{
gGL.getTexUnit(j)->activate();
- glClientActiveTextureARB(GL_TEXTURE0_ARB+j);
+ glClientActiveTexture(GL_TEXTURE0+j);
j == 0 ? gGL.getTexUnit(j)->enable(LLTexUnit::TT_TEXTURE) : gGL.getTexUnit(j)->disable();
}
}
@@ -1692,12 +2466,12 @@ void LLGLState::checkTextureChannels(const std::string& msg)
stop_glerror();
GLint activeTexture;
- glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
stop_glerror();
BOOL error = FALSE;
- if (activeTexture == GL_TEXTURE0_ARB)
+ if (activeTexture == GL_TEXTURE0)
{
GLint tex_env_mode = 0;
@@ -1720,12 +2494,12 @@ void LLGLState::checkTextureChannels(const std::string& msg)
"GL_TEXTURE_2D",
"GL_TEXTURE_COORD_ARRAY",
"GL_TEXTURE_1D",
- "GL_TEXTURE_CUBE_MAP_ARB",
+ "GL_TEXTURE_CUBE_MAP",
"GL_TEXTURE_GEN_S",
"GL_TEXTURE_GEN_T",
"GL_TEXTURE_GEN_Q",
"GL_TEXTURE_GEN_R",
- "GL_TEXTURE_RECTANGLE_ARB",
+ "GL_TEXTURE_RECTANGLE",
"GL_TEXTURE_2D_MULTISAMPLE"
};
@@ -1734,12 +2508,12 @@ void LLGLState::checkTextureChannels(const std::string& msg)
GL_TEXTURE_2D,
GL_TEXTURE_COORD_ARRAY,
GL_TEXTURE_1D,
- GL_TEXTURE_CUBE_MAP_ARB,
+ GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_GEN_S,
GL_TEXTURE_GEN_T,
GL_TEXTURE_GEN_Q,
GL_TEXTURE_GEN_R,
- GL_TEXTURE_RECTANGLE_ARB,
+ GL_TEXTURE_RECTANGLE,
GL_TEXTURE_2D_MULTISAMPLE
};
@@ -1749,13 +2523,13 @@ void LLGLState::checkTextureChannels(const std::string& msg)
glh::matrix4f identity;
identity.identity();
- for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++)
+ for (GLint i = 1; i < gGLManager.mNumTextureImageUnits; i++)
{
gGL.getTexUnit(i)->activate();
if (i < gGLManager.mNumTextureUnits)
{
- glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
+ glClientActiveTexture(GL_TEXTURE0+i);
stop_glerror();
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
stop_glerror();
@@ -1787,12 +2561,6 @@ void LLGLState::checkTextureChannels(const std::string& msg)
for (S32 j = (i == 0 ? 1 : 0);
j < 9; j++)
{
- if (j == 8 && !gGLManager.mHasTextureRectangle ||
- j == 9 && !gGLManager.mHasTextureMultisample)
- {
- continue;
- }
-
if (glIsEnabled(value[j]))
{
error = TRUE;
@@ -1840,7 +2608,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
stop_glerror();
gGL.getTexUnit(0)->activate();
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ glClientActiveTexture(GL_TEXTURE0);
stop_glerror();
if (error)
@@ -2283,36 +3051,29 @@ LLGLSquashToFarClip::~LLGLSquashToFarClip()
LLGLSyncFence::LLGLSyncFence()
{
-#ifdef GL_ARB_sync
mSync = 0;
-#endif
}
LLGLSyncFence::~LLGLSyncFence()
{
-#ifdef GL_ARB_sync
if (mSync)
{
glDeleteSync(mSync);
}
-#endif
}
void LLGLSyncFence::placeFence()
{
-#ifdef GL_ARB_sync
if (mSync)
{
glDeleteSync(mSync);
}
mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-#endif
}
bool LLGLSyncFence::isCompleted()
{
bool ret = true;
-#ifdef GL_ARB_sync
if (mSync)
{
GLenum status = glClientWaitSync(mSync, 0, 1);
@@ -2321,13 +3082,11 @@ bool LLGLSyncFence::isCompleted()
ret = false;
}
}
-#endif
return ret;
}
void LLGLSyncFence::wait()
{
-#ifdef GL_ARB_sync
if (mSync)
{
while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
@@ -2336,7 +3095,6 @@ void LLGLSyncFence::wait()
waits++;
}
}
-#endif
}
LLGLSPipelineSkyBox::LLGLSPipelineSkyBox()
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 52338364e6..e3c07604aa 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -47,6 +47,7 @@
extern BOOL gDebugGL;
extern BOOL gDebugSession;
+extern BOOL gDebugGLSession;
extern llofstream gFailLog;
#define LL_GL_ERRS LL_ERRS("RenderState")
@@ -75,50 +76,27 @@ public:
BOOL mInited;
BOOL mIsDisabled;
- // Extensions used by everyone
- BOOL mHasMultitexture;
- BOOL mHasATIMemInfo;
- BOOL mHasAMDAssociations;
- BOOL mHasNVXMemInfo;
- S32 mNumTextureUnits;
- BOOL mHasMipMapGeneration;
- BOOL mHasCompressedTextures;
- BOOL mHasFramebufferObject;
+ // OpenGL limits
S32 mMaxSamples;
- BOOL mHasBlendFuncSeparate;
-
- // ARB Extensions
- BOOL mHasVertexBufferObject;
- BOOL mHasVertexArrayObject;
- BOOL mHasSync;
- BOOL mHasMapBufferRange;
- BOOL mHasFlushBufferRange;
- BOOL mHasPBuffer;
- S32 mNumTextureImageUnits;
- BOOL mHasOcclusionQuery;
- BOOL mHasTimerQuery;
- BOOL mHasOcclusionQuery2;
- BOOL mHasPointParameters;
- BOOL mHasDrawBuffers;
- BOOL mHasDepthClamp;
- BOOL mHasTextureRectangle;
- BOOL mHasTextureMultisample;
- BOOL mHasTransformFeedback;
+ S32 mNumTextureImageUnits;
S32 mMaxSampleMaskWords;
S32 mMaxColorTextureSamples;
S32 mMaxDepthTextureSamples;
S32 mMaxIntegerSamples;
-
- // Other extensions.
- BOOL mHasAnisotropic;
- BOOL mHasARBEnvCombine;
- BOOL mHasCubeMap;
- BOOL mHasDebugOutput;
- BOOL mHassRGBTexture;
- BOOL mHassRGBFramebuffer;
- BOOL mHasTexturesRGBDecode;
-
+ S32 mGLMaxVertexRange;
+ S32 mGLMaxIndexRange;
+ S32 mGLMaxTextureSize;
+ F32 mMaxAnisotropy = 0.f;
+
+ // GL 4.x capabilities
+ bool mHasCubeMapArray = false;
+ bool mHasDebugOutput = false;
+ bool mHasTransformFeedback = false;
+ bool mHasAnisotropic = false;
+
// Vendor-specific extensions
+ bool mHasAMDAssociations = false;
+
BOOL mIsAMD;
BOOL mIsNVIDIA;
BOOL mIsIntel;
@@ -131,9 +109,6 @@ public:
// Whether this version of GL is good enough for SL to use
BOOL mHasRequirements;
- // Misc extensions
- BOOL mHasSeparateSpecularColor;
-
S32 mDriverVersionMajor;
S32 mDriverVersionMinor;
S32 mDriverVersionRelease;
@@ -144,9 +119,6 @@ public:
std::string mGLVersionString;
S32 mVRAM; // VRAM in MB
- S32 mGLMaxVertexRange;
- S32 mGLMaxIndexRange;
- S32 mGLMaxTextureSize;
void getPixelFormat(); // Get the best pixel format
@@ -412,9 +384,7 @@ public:
class LLGLSyncFence : public LLGLFence
{
public:
-#ifdef GL_ARB_sync
GLsync mSync;
-#endif
LLGLSyncFence();
virtual ~LLGLSyncFence();
diff --git a/indra/llrender/llglcommonfunc.cpp b/indra/llrender/llglcommonfunc.cpp
index e9ec28927f..04d29b9430 100644
--- a/indra/llrender/llglcommonfunc.cpp
+++ b/indra/llrender/llglcommonfunc.cpp
@@ -31,7 +31,8 @@ namespace LLGLCommonFunc
{
void selected_stencil_test()
{
- glStencilFunc(GL_ALWAYS, 2, 0xffff);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ // deprecated
+ //glStencilFunc(GL_ALWAYS, 2, 0xffff);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
}
}
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 3d93cc0762..b80680a3d2 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -41,278 +41,6 @@
# include "GL/glh_extensions.h"
# undef __APPLE__
-#elif LL_LINUX
-//----------------------------------------------------------------------------
-// LL_LINUX
-
-//----------------------------------------------------------------------------
-// Linux, MESA headers, but not necessarily assuming MESA runtime.
-// quotes so we get libraries/.../GL/ version
-#include "GL/gl.h"
-#include "GL/glext.h"
-#include "GL/glu.h"
-
-
-#if LL_LINUX && !LL_MESA_HEADLESS
-// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly
-# define __APPLE__
-# include "GL/glh_extensions.h"
-# undef __APPLE__
-
-/* Although SDL very likely ends up calling glXGetProcAddress() itself,
- if we use SDL_GL_GetProcAddress() then we get bogus addresses back on
- some systems. Weird. */
-/*# include "SDL/SDL.h"
- # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */
-#define GLX_GLXEXT_PROTOTYPES 1
-# include "GL/glx.h"
-# include "GL/glxext.h"
-// Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol
-// is considered 'legacy' but works on more machines.
-# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p))
-#endif // LL_LINUX && !LL_MESA_HEADLESS
-
-#if LL_LINUX && defined(WINGDIAPI)
-// WINGDIAPI gets set if we are using the linux nvidia gl.h header which needs
-// the functions below setting up.
-# define LL_LINUX_NV_GL_HEADERS 1
-#else
-# define LL_LINUX_NV_GL_HEADERS 0
-#endif // LL_LINUX && defined(WINGDIAPI)
-
-
-#if LL_LINUX_NV_GL_HEADERS
-// Missing functions when using nvidia headers:
-extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
-extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
-extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements;
-#endif // LL_LINUX_NV_GL_HEADERS
-
-// GL_ARB_vertex_array_object
-extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
-extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
-extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
-extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
-
-// GL_ARB_vertex_buffer_object
-extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
-extern PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB;
-extern PFNGLGENBUFFERSARBPROC glGenBuffersARB;
-extern PFNGLISBUFFERARBPROC glIsBufferARB;
-extern PFNGLBUFFERDATAARBPROC glBufferDataARB;
-extern PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB;
-extern PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB;
-extern PFNGLMAPBUFFERARBPROC glMapBufferARB;
-extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
-extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
-extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
-
-// GL_ARB_sync
-extern PFNGLFENCESYNCPROC glFenceSync;
-extern PFNGLISSYNCPROC glIsSync;
-extern PFNGLDELETESYNCPROC glDeleteSync;
-extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
-extern PFNGLWAITSYNCPROC glWaitSync;
-extern PFNGLGETINTEGER64VPROC glGetInteger64v;
-extern PFNGLGETSYNCIVPROC glGetSynciv;
-
-// GL_APPLE_flush_buffer_range
-extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE;
-
-// GL_ARB_map_buffer_range
-extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
-
-// GL_ATI_vertex_array_object
-extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
-extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
-extern PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI;
-extern PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI;
-extern PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI;
-extern PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI;
-extern PFNGLARRAYOBJECTATIPROC glArrayObjectATI;
-extern PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI;
-extern PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI;
-extern PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI;
-extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI;
-extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI;
-extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI;
-
-// GL_ARB_occlusion_query
-extern PFNGLGENQUERIESARBPROC glGenQueriesARB;
-extern PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB;
-extern PFNGLISQUERYARBPROC glIsQueryARB;
-extern PFNGLBEGINQUERYARBPROC glBeginQueryARB;
-extern PFNGLENDQUERYARBPROC glEndQueryARB;
-extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
-extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
-extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
-
-// GL_ARB_timer_query
-extern PFNGLQUERYCOUNTERPROC glQueryCounter;
-extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
-extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
-
-// GL_ARB_point_parameters
-extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
-extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
-
-// GL_ARB_shader_objects
-extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
-extern PFNGLGETHANDLEARBPROC glGetHandleARB;
-extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
-extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
-extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
-extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
-extern PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
-extern PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
-extern PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
-extern PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
-extern PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB;
-extern PFNGLUNIFORM1FARBPROC glUniform1fARB;
-extern PFNGLUNIFORM2FARBPROC glUniform2fARB;
-extern PFNGLUNIFORM3FARBPROC glUniform3fARB;
-extern PFNGLUNIFORM4FARBPROC glUniform4fARB;
-extern PFNGLUNIFORM1IARBPROC glUniform1iARB;
-extern PFNGLUNIFORM2IARBPROC glUniform2iARB;
-extern PFNGLUNIFORM3IARBPROC glUniform3iARB;
-extern PFNGLUNIFORM4IARBPROC glUniform4iARB;
-extern PFNGLUNIFORM1FVARBPROC glUniform1fvARB;
-extern PFNGLUNIFORM2FVARBPROC glUniform2fvARB;
-extern PFNGLUNIFORM3FVARBPROC glUniform3fvARB;
-extern PFNGLUNIFORM4FVARBPROC glUniform4fvARB;
-extern PFNGLUNIFORM1IVARBPROC glUniform1ivARB;
-extern PFNGLUNIFORM2IVARBPROC glUniform2ivARB;
-extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB;
-extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB;
-extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB;
-extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB;
-extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv;
-extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB;
-extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB;
-extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
-extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
-extern PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB;
-extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
-extern PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB;
-extern PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB;
-extern PFNGLGETUNIFORMIVARBPROC glGetUniformivARB;
-extern PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB;
-
-// GL_ARB_vertex_shader
-extern PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB;
-extern PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB;
-extern PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB;
-extern PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB;
-extern PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB;
-extern PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB;
-extern PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB;
-extern PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB;
-extern PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB;
-extern PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB;
-extern PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB;
-extern PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB;
-extern PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB;
-extern PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB;
-extern PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB;
-extern PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB;
-extern PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB;
-extern PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB;
-extern PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB;
-extern PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB;
-extern PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB;
-extern PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB;
-extern PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB;
-extern PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB;
-extern PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB;
-extern PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB;
-extern PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB;
-extern PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB;
-extern PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB;
-extern PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB;
-extern PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB;
-extern PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB;
-extern PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB;
-extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
-extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
-extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
-extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
-extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
-extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
-extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
-extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
-extern PFNGLBINDPROGRAMARBPROC glBindProgramARB;
-extern PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;
-extern PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
-extern PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB;
-extern PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB;
-extern PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB;
-extern PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB;
-extern PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB;
-extern PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB;
-extern PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB;
-extern PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB;
-extern PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB;
-extern PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB;
-extern PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB;
-extern PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB;
-extern PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
-extern PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB;
-extern PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB;
-extern PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB;
-extern PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB;
-extern PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB;
-extern PFNGLISPROGRAMARBPROC glIsProgramARB;
-extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;
-extern PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB;
-extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
-
-extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
-extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
-
-//GL_EXT_blend_func_separate
-extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
-
-//GL_ARB_framebuffer_object
-extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer;
-extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
-extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
-extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
-extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
-extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv;
-extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
-extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
-extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
-extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
-extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
-extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
-extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
-extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
-extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
-extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
-extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
-extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
-extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
-extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
-
-//GL_ARB_draw_buffers
-extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
-
-//GL_ARB_texture_multisample
-extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
-extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
-extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
-extern PFNGLSAMPLEMASKIPROC glSampleMaski;
-
-//transform feedback (4.0 core)
-extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
-extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
-extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
-extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
-extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
-
-
#elif LL_WINDOWS
//----------------------------------------------------------------------------
// LL_WINDOWS
@@ -328,251 +56,774 @@ extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
#include "GL/glext.h"
#include "GL/glh_extensions.h"
+// WGL_AMD_gpu_association
+extern PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD;
+extern PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD;
+extern PFNWGLGETCONTEXTGPUIDAMDPROC wglGetContextGPUIDAMD;
+extern PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC wglCreateAssociatedContextAMD;
+extern PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC wglCreateAssociatedContextAttribsAMD;
+extern PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC wglDeleteAssociatedContextAMD;
+extern PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC wglMakeAssociatedContextCurrentAMD;
+extern PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC wglGetCurrentAssociatedContextAMD;
+extern PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC wglBlitContextFramebufferAMD;
+
+// WGL_EXT_swap_control
+extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
+
// WGL_ARB_create_context
extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
-extern PFNGLGETSTRINGIPROC glGetStringi;
-
-// GL_ARB_vertex_buffer_object
-extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
-extern PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB;
-extern PFNGLGENBUFFERSARBPROC glGenBuffersARB;
-extern PFNGLISBUFFERARBPROC glIsBufferARB;
-extern PFNGLBUFFERDATAARBPROC glBufferDataARB;
-extern PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB;
-extern PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB;
-extern PFNGLMAPBUFFERARBPROC glMapBufferARB;
-extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
-extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
-extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
-
-// GL_ARB_vertex_array_object
-extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
-extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
-extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
-extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
-
-// GL_ARB_sync
-extern PFNGLFENCESYNCPROC glFenceSync;
-extern PFNGLISSYNCPROC glIsSync;
-extern PFNGLDELETESYNCPROC glDeleteSync;
-extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
-extern PFNGLWAITSYNCPROC glWaitSync;
-extern PFNGLGETINTEGER64VPROC glGetInteger64v;
-extern PFNGLGETSYNCIVPROC glGetSynciv;
-
-// GL_APPLE_flush_buffer_range
-extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE;
-
-// GL_ARB_map_buffer_range
-extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
-
-// GL_ATI_vertex_array_object
-extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
-extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
-extern PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI;
-extern PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI;
-extern PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI;
-extern PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI;
-extern PFNGLARRAYOBJECTATIPROC glArrayObjectATI;
-extern PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI;
-extern PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI;
-extern PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI;
-extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI;
-extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI;
-extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI;
-
-extern PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD;
-extern PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD;
-extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
-
-// GL_ARB_occlusion_query
-extern PFNGLGENQUERIESARBPROC glGenQueriesARB;
-extern PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB;
-extern PFNGLISQUERYARBPROC glIsQueryARB;
-extern PFNGLBEGINQUERYARBPROC glBeginQueryARB;
-extern PFNGLENDQUERYARBPROC glEndQueryARB;
-extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
-extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
-extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
-
-// GL_ARB_timer_query
-extern PFNGLQUERYCOUNTERPROC glQueryCounter;
-extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
-extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
-
-
-// GL_ARB_point_parameters
-extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
-extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
-
-// GL_ARB_shader_objects
-extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
-extern PFNGLGETHANDLEARBPROC glGetHandleARB;
-extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
-extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
-extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
-extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
-extern PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
-extern PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
-extern PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
-extern PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
-extern PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB;
-extern PFNGLUNIFORM1FARBPROC glUniform1fARB;
-extern PFNGLUNIFORM2FARBPROC glUniform2fARB;
-extern PFNGLUNIFORM3FARBPROC glUniform3fARB;
-extern PFNGLUNIFORM4FARBPROC glUniform4fARB;
-extern PFNGLUNIFORM1IARBPROC glUniform1iARB;
-extern PFNGLUNIFORM2IARBPROC glUniform2iARB;
-extern PFNGLUNIFORM3IARBPROC glUniform3iARB;
-extern PFNGLUNIFORM4IARBPROC glUniform4iARB;
-extern PFNGLUNIFORM1FVARBPROC glUniform1fvARB;
-extern PFNGLUNIFORM2FVARBPROC glUniform2fvARB;
-extern PFNGLUNIFORM3FVARBPROC glUniform3fvARB;
-extern PFNGLUNIFORM4FVARBPROC glUniform4fvARB;
-extern PFNGLUNIFORM1IVARBPROC glUniform1ivARB;
-extern PFNGLUNIFORM2IVARBPROC glUniform2ivARB;
-extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB;
-extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB;
-extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB;
-extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB;
+
+// GL_VERSION_1_3
+extern PFNGLACTIVETEXTUREPROC glActiveTexture;
+extern PFNGLSAMPLECOVERAGEPROC glSampleCoverage;
+extern PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D;
+extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
+extern PFNGLCOMPRESSEDTEXIMAGE1DPROC glCompressedTexImage1D;
+extern PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D;
+extern PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D;
+extern PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D;
+extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
+extern PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
+extern PFNGLMULTITEXCOORD1DPROC glMultiTexCoord1d;
+extern PFNGLMULTITEXCOORD1DVPROC glMultiTexCoord1dv;
+extern PFNGLMULTITEXCOORD1FPROC glMultiTexCoord1f;
+extern PFNGLMULTITEXCOORD1FVPROC glMultiTexCoord1fv;
+extern PFNGLMULTITEXCOORD1IPROC glMultiTexCoord1i;
+extern PFNGLMULTITEXCOORD1IVPROC glMultiTexCoord1iv;
+extern PFNGLMULTITEXCOORD1SPROC glMultiTexCoord1s;
+extern PFNGLMULTITEXCOORD1SVPROC glMultiTexCoord1sv;
+extern PFNGLMULTITEXCOORD2DPROC glMultiTexCoord2d;
+extern PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv;
+extern PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f;
+extern PFNGLMULTITEXCOORD2FVPROC glMultiTexCoord2fv;
+extern PFNGLMULTITEXCOORD2IPROC glMultiTexCoord2i;
+extern PFNGLMULTITEXCOORD2IVPROC glMultiTexCoord2iv;
+extern PFNGLMULTITEXCOORD2SPROC glMultiTexCoord2s;
+extern PFNGLMULTITEXCOORD2SVPROC glMultiTexCoord2sv;
+extern PFNGLMULTITEXCOORD3DPROC glMultiTexCoord3d;
+extern PFNGLMULTITEXCOORD3DVPROC glMultiTexCoord3dv;
+extern PFNGLMULTITEXCOORD3FPROC glMultiTexCoord3f;
+extern PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv;
+extern PFNGLMULTITEXCOORD3IPROC glMultiTexCoord3i;
+extern PFNGLMULTITEXCOORD3IVPROC glMultiTexCoord3iv;
+extern PFNGLMULTITEXCOORD3SPROC glMultiTexCoord3s;
+extern PFNGLMULTITEXCOORD3SVPROC glMultiTexCoord3sv;
+extern PFNGLMULTITEXCOORD4DPROC glMultiTexCoord4d;
+extern PFNGLMULTITEXCOORD4DVPROC glMultiTexCoord4dv;
+extern PFNGLMULTITEXCOORD4FPROC glMultiTexCoord4f;
+extern PFNGLMULTITEXCOORD4FVPROC glMultiTexCoord4fv;
+extern PFNGLMULTITEXCOORD4IPROC glMultiTexCoord4i;
+extern PFNGLMULTITEXCOORD4IVPROC glMultiTexCoord4iv;
+extern PFNGLMULTITEXCOORD4SPROC glMultiTexCoord4s;
+extern PFNGLMULTITEXCOORD4SVPROC glMultiTexCoord4sv;
+extern PFNGLLOADTRANSPOSEMATRIXFPROC glLoadTransposeMatrixf;
+extern PFNGLLOADTRANSPOSEMATRIXDPROC glLoadTransposeMatrixd;
+extern PFNGLMULTTRANSPOSEMATRIXFPROC glMultTransposeMatrixf;
+extern PFNGLMULTTRANSPOSEMATRIXDPROC glMultTransposeMatrixd;
+
+// GL_VERSION_1_4
+extern PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
+extern PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays;
+extern PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements;
+extern PFNGLPOINTPARAMETERFPROC glPointParameterf;
+extern PFNGLPOINTPARAMETERFVPROC glPointParameterfv;
+extern PFNGLPOINTPARAMETERIPROC glPointParameteri;
+extern PFNGLPOINTPARAMETERIVPROC glPointParameteriv;
+extern PFNGLFOGCOORDFPROC glFogCoordf;
+extern PFNGLFOGCOORDFVPROC glFogCoordfv;
+extern PFNGLFOGCOORDDPROC glFogCoordd;
+extern PFNGLFOGCOORDDVPROC glFogCoorddv;
+extern PFNGLFOGCOORDPOINTERPROC glFogCoordPointer;
+extern PFNGLSECONDARYCOLOR3BPROC glSecondaryColor3b;
+extern PFNGLSECONDARYCOLOR3BVPROC glSecondaryColor3bv;
+extern PFNGLSECONDARYCOLOR3DPROC glSecondaryColor3d;
+extern PFNGLSECONDARYCOLOR3DVPROC glSecondaryColor3dv;
+extern PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f;
+extern PFNGLSECONDARYCOLOR3FVPROC glSecondaryColor3fv;
+extern PFNGLSECONDARYCOLOR3IPROC glSecondaryColor3i;
+extern PFNGLSECONDARYCOLOR3IVPROC glSecondaryColor3iv;
+extern PFNGLSECONDARYCOLOR3SPROC glSecondaryColor3s;
+extern PFNGLSECONDARYCOLOR3SVPROC glSecondaryColor3sv;
+extern PFNGLSECONDARYCOLOR3UBPROC glSecondaryColor3ub;
+extern PFNGLSECONDARYCOLOR3UBVPROC glSecondaryColor3ubv;
+extern PFNGLSECONDARYCOLOR3UIPROC glSecondaryColor3ui;
+extern PFNGLSECONDARYCOLOR3UIVPROC glSecondaryColor3uiv;
+extern PFNGLSECONDARYCOLOR3USPROC glSecondaryColor3us;
+extern PFNGLSECONDARYCOLOR3USVPROC glSecondaryColor3usv;
+extern PFNGLSECONDARYCOLORPOINTERPROC glSecondaryColorPointer;
+extern PFNGLWINDOWPOS2DPROC glWindowPos2d;
+extern PFNGLWINDOWPOS2DVPROC glWindowPos2dv;
+extern PFNGLWINDOWPOS2FPROC glWindowPos2f;
+extern PFNGLWINDOWPOS2FVPROC glWindowPos2fv;
+extern PFNGLWINDOWPOS2IPROC glWindowPos2i;
+extern PFNGLWINDOWPOS2IVPROC glWindowPos2iv;
+extern PFNGLWINDOWPOS2SPROC glWindowPos2s;
+extern PFNGLWINDOWPOS2SVPROC glWindowPos2sv;
+extern PFNGLWINDOWPOS3DPROC glWindowPos3d;
+extern PFNGLWINDOWPOS3DVPROC glWindowPos3dv;
+extern PFNGLWINDOWPOS3FPROC glWindowPos3f;
+extern PFNGLWINDOWPOS3FVPROC glWindowPos3fv;
+extern PFNGLWINDOWPOS3IPROC glWindowPos3i;
+extern PFNGLWINDOWPOS3IVPROC glWindowPos3iv;
+extern PFNGLWINDOWPOS3SPROC glWindowPos3s;
+extern PFNGLWINDOWPOS3SVPROC glWindowPos3sv;
+
+// GL_VERSION_1_5
+extern PFNGLGENQUERIESPROC glGenQueries;
+extern PFNGLDELETEQUERIESPROC glDeleteQueries;
+extern PFNGLISQUERYPROC glIsQuery;
+extern PFNGLBEGINQUERYPROC glBeginQuery;
+extern PFNGLENDQUERYPROC glEndQuery;
+extern PFNGLGETQUERYIVPROC glGetQueryiv;
+extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv;
+extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
+extern PFNGLBINDBUFFERPROC glBindBuffer;
+extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
+extern PFNGLGENBUFFERSPROC glGenBuffers;
+extern PFNGLISBUFFERPROC glIsBuffer;
+extern PFNGLBUFFERDATAPROC glBufferData;
+extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
+extern PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData;
+extern PFNGLMAPBUFFERPROC glMapBuffer;
+extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
+extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
+extern PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv;
+
+// GL_VERSION_2_0
+extern PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate;
+extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
+extern PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate;
+extern PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
+extern PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate;
+extern PFNGLATTACHSHADERPROC glAttachShader;
+extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
+extern PFNGLCOMPILESHADERPROC glCompileShader;
+extern PFNGLCREATEPROGRAMPROC glCreateProgram;
+extern PFNGLCREATESHADERPROC glCreateShader;
+extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
+extern PFNGLDELETESHADERPROC glDeleteShader;
+extern PFNGLDETACHSHADERPROC glDetachShader;
+extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
+extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+extern PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib;
+extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
+extern PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders;
+extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
+extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
+extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+extern PFNGLGETSHADERIVPROC glGetShaderiv;
+extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+extern PFNGLGETSHADERSOURCEPROC glGetShaderSource;
+extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+extern PFNGLGETUNIFORMFVPROC glGetUniformfv;
+extern PFNGLGETUNIFORMIVPROC glGetUniformiv;
+extern PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv;
+extern PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv;
+extern PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv;
+extern PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv;
+extern PFNGLISPROGRAMPROC glIsProgram;
+extern PFNGLISSHADERPROC glIsShader;
+extern PFNGLLINKPROGRAMPROC glLinkProgram;
+extern PFNGLSHADERSOURCEPROC glShaderSource;
+extern PFNGLUSEPROGRAMPROC glUseProgram;
+extern PFNGLUNIFORM1FPROC glUniform1f;
+extern PFNGLUNIFORM2FPROC glUniform2f;
+extern PFNGLUNIFORM3FPROC glUniform3f;
+extern PFNGLUNIFORM4FPROC glUniform4f;
+extern PFNGLUNIFORM1IPROC glUniform1i;
+extern PFNGLUNIFORM2IPROC glUniform2i;
+extern PFNGLUNIFORM3IPROC glUniform3i;
+extern PFNGLUNIFORM4IPROC glUniform4i;
+extern PFNGLUNIFORM1FVPROC glUniform1fv;
+extern PFNGLUNIFORM2FVPROC glUniform2fv;
+extern PFNGLUNIFORM3FVPROC glUniform3fv;
+extern PFNGLUNIFORM4FVPROC glUniform4fv;
+extern PFNGLUNIFORM1IVPROC glUniform1iv;
+extern PFNGLUNIFORM2IVPROC glUniform2iv;
+extern PFNGLUNIFORM3IVPROC glUniform3iv;
+extern PFNGLUNIFORM4IVPROC glUniform4iv;
+extern PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv;
+extern PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv;
+extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
+extern PFNGLVALIDATEPROGRAMPROC glValidateProgram;
+extern PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d;
+extern PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv;
+extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f;
+extern PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv;
+extern PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s;
+extern PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv;
+extern PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d;
+extern PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv;
+extern PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f;
+extern PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv;
+extern PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s;
+extern PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv;
+extern PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d;
+extern PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv;
+extern PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f;
+extern PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv;
+extern PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s;
+extern PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv;
+extern PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv;
+extern PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv;
+extern PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv;
+extern PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub;
+extern PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv;
+extern PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv;
+extern PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv;
+extern PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv;
+extern PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d;
+extern PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv;
+extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f;
+extern PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv;
+extern PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv;
+extern PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s;
+extern PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv;
+extern PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv;
+extern PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv;
+extern PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv;
+extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
+
+// GL_VERSION_2_1
+extern PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv;
+extern PFNGLUNIFORMMATRIX3X2FVPROC glUniformMatrix3x2fv;
+extern PFNGLUNIFORMMATRIX2X4FVPROC glUniformMatrix2x4fv;
+extern PFNGLUNIFORMMATRIX4X2FVPROC glUniformMatrix4x2fv;
extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv;
-extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB;
-extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB;
-extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
-extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
-extern PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB;
-extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
-extern PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB;
-extern PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB;
-extern PFNGLGETUNIFORMIVARBPROC glGetUniformivARB;
-extern PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB;
-
-// GL_ARB_vertex_shader
-extern PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB;
-extern PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB;
-extern PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB;
-extern PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB;
-extern PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB;
-extern PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB;
-extern PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB;
-extern PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB;
-extern PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB;
-extern PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB;
-extern PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB;
-extern PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB;
-extern PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB;
-extern PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB;
-extern PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB;
-extern PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB;
-extern PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB;
-extern PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB;
-extern PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB;
-extern PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB;
-extern PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB;
-extern PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB;
-extern PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB;
-extern PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB;
-extern PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB;
-extern PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB;
-extern PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB;
-extern PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB;
-extern PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB;
-extern PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB;
-extern PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB;
-extern PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB;
-extern PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB;
-extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
-extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
-extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
-extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
-extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
-extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
-extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
-extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
-extern PFNGLBINDPROGRAMARBPROC glBindProgramARB;
-extern PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;
-extern PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
-extern PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB;
-extern PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB;
-extern PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB;
-extern PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB;
-extern PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB;
-extern PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB;
-extern PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB;
-extern PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB;
-extern PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB;
-extern PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB;
-extern PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB;
-extern PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB;
-extern PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
-extern PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB;
-extern PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB;
-extern PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB;
-extern PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB;
-extern PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB;
-extern PFNGLISPROGRAMARBPROC glIsProgramARB;
-extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;
-extern PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB;
-extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
+extern PFNGLUNIFORMMATRIX4X3FVPROC glUniformMatrix4x3fv;
+
+// GL_VERSION_3_0
+extern PFNGLCOLORMASKIPROC glColorMaski;
+extern PFNGLGETBOOLEANI_VPROC glGetBooleani_v;
+extern PFNGLGETINTEGERI_VPROC glGetIntegeri_v;
+extern PFNGLENABLEIPROC glEnablei;
+extern PFNGLDISABLEIPROC glDisablei;
+extern PFNGLISENABLEDIPROC glIsEnabledi;
+extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
+extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
+extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
+extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
+extern PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glGetTransformFeedbackVarying;
+extern PFNGLCLAMPCOLORPROC glClampColor;
+extern PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender;
+extern PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender;
+extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
+extern PFNGLGETVERTEXATTRIBIIVPROC glGetVertexAttribIiv;
+extern PFNGLGETVERTEXATTRIBIUIVPROC glGetVertexAttribIuiv;
+extern PFNGLVERTEXATTRIBI1IPROC glVertexAttribI1i;
+extern PFNGLVERTEXATTRIBI2IPROC glVertexAttribI2i;
+extern PFNGLVERTEXATTRIBI3IPROC glVertexAttribI3i;
+extern PFNGLVERTEXATTRIBI4IPROC glVertexAttribI4i;
+extern PFNGLVERTEXATTRIBI1UIPROC glVertexAttribI1ui;
+extern PFNGLVERTEXATTRIBI2UIPROC glVertexAttribI2ui;
+extern PFNGLVERTEXATTRIBI3UIPROC glVertexAttribI3ui;
+extern PFNGLVERTEXATTRIBI4UIPROC glVertexAttribI4ui;
+extern PFNGLVERTEXATTRIBI1IVPROC glVertexAttribI1iv;
+extern PFNGLVERTEXATTRIBI2IVPROC glVertexAttribI2iv;
+extern PFNGLVERTEXATTRIBI3IVPROC glVertexAttribI3iv;
+extern PFNGLVERTEXATTRIBI4IVPROC glVertexAttribI4iv;
+extern PFNGLVERTEXATTRIBI1UIVPROC glVertexAttribI1uiv;
+extern PFNGLVERTEXATTRIBI2UIVPROC glVertexAttribI2uiv;
+extern PFNGLVERTEXATTRIBI3UIVPROC glVertexAttribI3uiv;
+extern PFNGLVERTEXATTRIBI4UIVPROC glVertexAttribI4uiv;
+extern PFNGLVERTEXATTRIBI4BVPROC glVertexAttribI4bv;
+extern PFNGLVERTEXATTRIBI4SVPROC glVertexAttribI4sv;
+extern PFNGLVERTEXATTRIBI4UBVPROC glVertexAttribI4ubv;
+extern PFNGLVERTEXATTRIBI4USVPROC glVertexAttribI4usv;
+extern PFNGLGETUNIFORMUIVPROC glGetUniformuiv;
+extern PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation;
+extern PFNGLGETFRAGDATALOCATIONPROC glGetFragDataLocation;
+extern PFNGLUNIFORM1UIPROC glUniform1ui;
+extern PFNGLUNIFORM2UIPROC glUniform2ui;
+extern PFNGLUNIFORM3UIPROC glUniform3ui;
+extern PFNGLUNIFORM4UIPROC glUniform4ui;
+extern PFNGLUNIFORM1UIVPROC glUniform1uiv;
+extern PFNGLUNIFORM2UIVPROC glUniform2uiv;
+extern PFNGLUNIFORM3UIVPROC glUniform3uiv;
+extern PFNGLUNIFORM4UIVPROC glUniform4uiv;
+extern PFNGLTEXPARAMETERIIVPROC glTexParameterIiv;
+extern PFNGLTEXPARAMETERIUIVPROC glTexParameterIuiv;
+extern PFNGLGETTEXPARAMETERIIVPROC glGetTexParameterIiv;
+extern PFNGLGETTEXPARAMETERIUIVPROC glGetTexParameterIuiv;
+extern PFNGLCLEARBUFFERIVPROC glClearBufferiv;
+extern PFNGLCLEARBUFFERUIVPROC glClearBufferuiv;
+extern PFNGLCLEARBUFFERFVPROC glClearBufferfv;
+extern PFNGLCLEARBUFFERFIPROC glClearBufferfi;
+extern PFNGLGETSTRINGIPROC glGetStringi;
+extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer;
+extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
+extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
+extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
+extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
+extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv;
+extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
+extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
+extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
+extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
+extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
+extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
+extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
+extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
+extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
+extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
+extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
+extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
+extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
+extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
+extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
+extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
+extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
+extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
+extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
+extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
+
+// GL_VERSION_3_1
+extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
+extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
+extern PFNGLTEXBUFFERPROC glTexBuffer;
+extern PFNGLPRIMITIVERESTARTINDEXPROC glPrimitiveRestartIndex;
+extern PFNGLCOPYBUFFERSUBDATAPROC glCopyBufferSubData;
+extern PFNGLGETUNIFORMINDICESPROC glGetUniformIndices;
+extern PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv;
+extern PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformName;
+extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
+extern PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv;
+extern PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName;
+extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
+
+// GL_VERSION_3_2
+extern PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
+extern PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glDrawRangeElementsBaseVertex;
+extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
+extern PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glMultiDrawElementsBaseVertex;
+extern PFNGLPROVOKINGVERTEXPROC glProvokingVertex;
+extern PFNGLFENCESYNCPROC glFenceSync;
+extern PFNGLISSYNCPROC glIsSync;
+extern PFNGLDELETESYNCPROC glDeleteSync;
+extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
+extern PFNGLWAITSYNCPROC glWaitSync;
+extern PFNGLGETINTEGER64VPROC glGetInteger64v;
+extern PFNGLGETSYNCIVPROC glGetSynciv;
+extern PFNGLGETINTEGER64I_VPROC glGetInteger64i_v;
+extern PFNGLGETBUFFERPARAMETERI64VPROC glGetBufferParameteri64v;
+extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
+extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
+extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
+extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
+extern PFNGLSAMPLEMASKIPROC glSampleMaski;
+
+// GL_VERSION_3_3
+extern PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glBindFragDataLocationIndexed;
+extern PFNGLGETFRAGDATAINDEXPROC glGetFragDataIndex;
+extern PFNGLGENSAMPLERSPROC glGenSamplers;
+extern PFNGLDELETESAMPLERSPROC glDeleteSamplers;
+extern PFNGLISSAMPLERPROC glIsSampler;
+extern PFNGLBINDSAMPLERPROC glBindSampler;
+extern PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri;
+extern PFNGLSAMPLERPARAMETERIVPROC glSamplerParameteriv;
+extern PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf;
+extern PFNGLSAMPLERPARAMETERFVPROC glSamplerParameterfv;
+extern PFNGLSAMPLERPARAMETERIIVPROC glSamplerParameterIiv;
+extern PFNGLSAMPLERPARAMETERIUIVPROC glSamplerParameterIuiv;
+extern PFNGLGETSAMPLERPARAMETERIVPROC glGetSamplerParameteriv;
+extern PFNGLGETSAMPLERPARAMETERIIVPROC glGetSamplerParameterIiv;
+extern PFNGLGETSAMPLERPARAMETERFVPROC glGetSamplerParameterfv;
+extern PFNGLGETSAMPLERPARAMETERIUIVPROC glGetSamplerParameterIuiv;
+extern PFNGLQUERYCOUNTERPROC glQueryCounter;
+extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
+extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
+extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
+extern PFNGLVERTEXATTRIBP1UIPROC glVertexAttribP1ui;
+extern PFNGLVERTEXATTRIBP1UIVPROC glVertexAttribP1uiv;
+extern PFNGLVERTEXATTRIBP2UIPROC glVertexAttribP2ui;
+extern PFNGLVERTEXATTRIBP2UIVPROC glVertexAttribP2uiv;
+extern PFNGLVERTEXATTRIBP3UIPROC glVertexAttribP3ui;
+extern PFNGLVERTEXATTRIBP3UIVPROC glVertexAttribP3uiv;
+extern PFNGLVERTEXATTRIBP4UIPROC glVertexAttribP4ui;
+extern PFNGLVERTEXATTRIBP4UIVPROC glVertexAttribP4uiv;
+extern PFNGLVERTEXP2UIPROC glVertexP2ui;
+extern PFNGLVERTEXP2UIVPROC glVertexP2uiv;
+extern PFNGLVERTEXP3UIPROC glVertexP3ui;
+extern PFNGLVERTEXP3UIVPROC glVertexP3uiv;
+extern PFNGLVERTEXP4UIPROC glVertexP4ui;
+extern PFNGLVERTEXP4UIVPROC glVertexP4uiv;
+extern PFNGLTEXCOORDP1UIPROC glTexCoordP1ui;
+extern PFNGLTEXCOORDP1UIVPROC glTexCoordP1uiv;
+extern PFNGLTEXCOORDP2UIPROC glTexCoordP2ui;
+extern PFNGLTEXCOORDP2UIVPROC glTexCoordP2uiv;
+extern PFNGLTEXCOORDP3UIPROC glTexCoordP3ui;
+extern PFNGLTEXCOORDP3UIVPROC glTexCoordP3uiv;
+extern PFNGLTEXCOORDP4UIPROC glTexCoordP4ui;
+extern PFNGLTEXCOORDP4UIVPROC glTexCoordP4uiv;
+extern PFNGLMULTITEXCOORDP1UIPROC glMultiTexCoordP1ui;
+extern PFNGLMULTITEXCOORDP1UIVPROC glMultiTexCoordP1uiv;
+extern PFNGLMULTITEXCOORDP2UIPROC glMultiTexCoordP2ui;
+extern PFNGLMULTITEXCOORDP2UIVPROC glMultiTexCoordP2uiv;
+extern PFNGLMULTITEXCOORDP3UIPROC glMultiTexCoordP3ui;
+extern PFNGLMULTITEXCOORDP3UIVPROC glMultiTexCoordP3uiv;
+extern PFNGLMULTITEXCOORDP4UIPROC glMultiTexCoordP4ui;
+extern PFNGLMULTITEXCOORDP4UIVPROC glMultiTexCoordP4uiv;
+extern PFNGLNORMALP3UIPROC glNormalP3ui;
+extern PFNGLNORMALP3UIVPROC glNormalP3uiv;
+extern PFNGLCOLORP3UIPROC glColorP3ui;
+extern PFNGLCOLORP3UIVPROC glColorP3uiv;
+extern PFNGLCOLORP4UIPROC glColorP4ui;
+extern PFNGLCOLORP4UIVPROC glColorP4uiv;
+extern PFNGLSECONDARYCOLORP3UIPROC glSecondaryColorP3ui;
+extern PFNGLSECONDARYCOLORP3UIVPROC glSecondaryColorP3uiv;
+
+// GL_VERSION_4_0
+extern PFNGLMINSAMPLESHADINGPROC glMinSampleShading;
+extern PFNGLBLENDEQUATIONIPROC glBlendEquationi;
+extern PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei;
+extern PFNGLBLENDFUNCIPROC glBlendFunci;
+extern PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei;
+extern PFNGLDRAWARRAYSINDIRECTPROC glDrawArraysIndirect;
+extern PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect;
+extern PFNGLUNIFORM1DPROC glUniform1d;
+extern PFNGLUNIFORM2DPROC glUniform2d;
+extern PFNGLUNIFORM3DPROC glUniform3d;
+extern PFNGLUNIFORM4DPROC glUniform4d;
+extern PFNGLUNIFORM1DVPROC glUniform1dv;
+extern PFNGLUNIFORM2DVPROC glUniform2dv;
+extern PFNGLUNIFORM3DVPROC glUniform3dv;
+extern PFNGLUNIFORM4DVPROC glUniform4dv;
+extern PFNGLUNIFORMMATRIX2DVPROC glUniformMatrix2dv;
+extern PFNGLUNIFORMMATRIX3DVPROC glUniformMatrix3dv;
+extern PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv;
+extern PFNGLUNIFORMMATRIX2X3DVPROC glUniformMatrix2x3dv;
+extern PFNGLUNIFORMMATRIX2X4DVPROC glUniformMatrix2x4dv;
+extern PFNGLUNIFORMMATRIX3X2DVPROC glUniformMatrix3x2dv;
+extern PFNGLUNIFORMMATRIX3X4DVPROC glUniformMatrix3x4dv;
+extern PFNGLUNIFORMMATRIX4X2DVPROC glUniformMatrix4x2dv;
+extern PFNGLUNIFORMMATRIX4X3DVPROC glUniformMatrix4x3dv;
+extern PFNGLGETUNIFORMDVPROC glGetUniformdv;
+extern PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glGetSubroutineUniformLocation;
+extern PFNGLGETSUBROUTINEINDEXPROC glGetSubroutineIndex;
+extern PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glGetActiveSubroutineUniformiv;
+extern PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glGetActiveSubroutineUniformName;
+extern PFNGLGETACTIVESUBROUTINENAMEPROC glGetActiveSubroutineName;
+extern PFNGLUNIFORMSUBROUTINESUIVPROC glUniformSubroutinesuiv;
+extern PFNGLGETUNIFORMSUBROUTINEUIVPROC glGetUniformSubroutineuiv;
+extern PFNGLGETPROGRAMSTAGEIVPROC glGetProgramStageiv;
+extern PFNGLPATCHPARAMETERIPROC glPatchParameteri;
+extern PFNGLPATCHPARAMETERFVPROC glPatchParameterfv;
+extern PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback;
+extern PFNGLDELETETRANSFORMFEEDBACKSPROC glDeleteTransformFeedbacks;
+extern PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks;
+extern PFNGLISTRANSFORMFEEDBACKPROC glIsTransformFeedback;
+extern PFNGLPAUSETRANSFORMFEEDBACKPROC glPauseTransformFeedback;
+extern PFNGLRESUMETRANSFORMFEEDBACKPROC glResumeTransformFeedback;
+extern PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback;
+extern PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glDrawTransformFeedbackStream;
+extern PFNGLBEGINQUERYINDEXEDPROC glBeginQueryIndexed;
+extern PFNGLENDQUERYINDEXEDPROC glEndQueryIndexed;
+extern PFNGLGETQUERYINDEXEDIVPROC glGetQueryIndexediv;
+
+ // GL_VERSION_4_1
+extern PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler;
+extern PFNGLSHADERBINARYPROC glShaderBinary;
+extern PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat;
+extern PFNGLDEPTHRANGEFPROC glDepthRangef;
+extern PFNGLCLEARDEPTHFPROC glClearDepthf;
+extern PFNGLGETPROGRAMBINARYPROC glGetProgramBinary;
+extern PFNGLPROGRAMBINARYPROC glProgramBinary;
+extern PFNGLPROGRAMPARAMETERIPROC glProgramParameteri;
+extern PFNGLUSEPROGRAMSTAGESPROC glUseProgramStages;
+extern PFNGLACTIVESHADERPROGRAMPROC glActiveShaderProgram;
+extern PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv;
+extern PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline;
+extern PFNGLDELETEPROGRAMPIPELINESPROC glDeleteProgramPipelines;
+extern PFNGLGENPROGRAMPIPELINESPROC glGenProgramPipelines;
+extern PFNGLISPROGRAMPIPELINEPROC glIsProgramPipeline;
+extern PFNGLGETPROGRAMPIPELINEIVPROC glGetProgramPipelineiv;
+extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;
+extern PFNGLPROGRAMUNIFORM1IVPROC glProgramUniform1iv;
+extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f;
+extern PFNGLPROGRAMUNIFORM1FVPROC glProgramUniform1fv;
+extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d;
+extern PFNGLPROGRAMUNIFORM1DVPROC glProgramUniform1dv;
+extern PFNGLPROGRAMUNIFORM1UIPROC glProgramUniform1ui;
+extern PFNGLPROGRAMUNIFORM1UIVPROC glProgramUniform1uiv;
+extern PFNGLPROGRAMUNIFORM2IPROC glProgramUniform2i;
+extern PFNGLPROGRAMUNIFORM2IVPROC glProgramUniform2iv;
+extern PFNGLPROGRAMUNIFORM2FPROC glProgramUniform2f;
+extern PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv;
+extern PFNGLPROGRAMUNIFORM2DPROC glProgramUniform2d;
+extern PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv;
+extern PFNGLPROGRAMUNIFORM2UIPROC glProgramUniform2ui;
+extern PFNGLPROGRAMUNIFORM2UIVPROC glProgramUniform2uiv;
+extern PFNGLPROGRAMUNIFORM3IPROC glProgramUniform3i;
+extern PFNGLPROGRAMUNIFORM3IVPROC glProgramUniform3iv;
+extern PFNGLPROGRAMUNIFORM3FPROC glProgramUniform3f;
+extern PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv;
+extern PFNGLPROGRAMUNIFORM3DPROC glProgramUniform3d;
+extern PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv;
+extern PFNGLPROGRAMUNIFORM3UIPROC glProgramUniform3ui;
+extern PFNGLPROGRAMUNIFORM3UIVPROC glProgramUniform3uiv;
+extern PFNGLPROGRAMUNIFORM4IPROC glProgramUniform4i;
+extern PFNGLPROGRAMUNIFORM4IVPROC glProgramUniform4iv;
+extern PFNGLPROGRAMUNIFORM4FPROC glProgramUniform4f;
+extern PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv;
+extern PFNGLPROGRAMUNIFORM4DPROC glProgramUniform4d;
+extern PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv;
+extern PFNGLPROGRAMUNIFORM4UIPROC glProgramUniform4ui;
+extern PFNGLPROGRAMUNIFORM4UIVPROC glProgramUniform4uiv;
+extern PFNGLPROGRAMUNIFORMMATRIX2FVPROC glProgramUniformMatrix2fv;
+extern PFNGLPROGRAMUNIFORMMATRIX3FVPROC glProgramUniformMatrix3fv;
+extern PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv;
+extern PFNGLPROGRAMUNIFORMMATRIX2DVPROC glProgramUniformMatrix2dv;
+extern PFNGLPROGRAMUNIFORMMATRIX3DVPROC glProgramUniformMatrix3dv;
+extern PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv;
+extern PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glProgramUniformMatrix2x3fv;
+extern PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glProgramUniformMatrix3x2fv;
+extern PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glProgramUniformMatrix2x4fv;
+extern PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glProgramUniformMatrix4x2fv;
+extern PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glProgramUniformMatrix3x4fv;
+extern PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glProgramUniformMatrix4x3fv;
+extern PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glProgramUniformMatrix2x3dv;
+extern PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glProgramUniformMatrix3x2dv;
+extern PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glProgramUniformMatrix2x4dv;
+extern PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glProgramUniformMatrix4x2dv;
+extern PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glProgramUniformMatrix3x4dv;
+extern PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glProgramUniformMatrix4x3dv;
+extern PFNGLVALIDATEPROGRAMPIPELINEPROC glValidateProgramPipeline;
+extern PFNGLGETPROGRAMPIPELINEINFOLOGPROC glGetProgramPipelineInfoLog;
+extern PFNGLVERTEXATTRIBL1DPROC glVertexAttribL1d;
+extern PFNGLVERTEXATTRIBL2DPROC glVertexAttribL2d;
+extern PFNGLVERTEXATTRIBL3DPROC glVertexAttribL3d;
+extern PFNGLVERTEXATTRIBL4DPROC glVertexAttribL4d;
+extern PFNGLVERTEXATTRIBL1DVPROC glVertexAttribL1dv;
+extern PFNGLVERTEXATTRIBL2DVPROC glVertexAttribL2dv;
+extern PFNGLVERTEXATTRIBL3DVPROC glVertexAttribL3dv;
+extern PFNGLVERTEXATTRIBL4DVPROC glVertexAttribL4dv;
+extern PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer;
+extern PFNGLGETVERTEXATTRIBLDVPROC glGetVertexAttribLdv;
+extern PFNGLVIEWPORTARRAYVPROC glViewportArrayv;
+extern PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf;
+extern PFNGLVIEWPORTINDEXEDFVPROC glViewportIndexedfv;
+extern PFNGLSCISSORARRAYVPROC glScissorArrayv;
+extern PFNGLSCISSORINDEXEDPROC glScissorIndexed;
+extern PFNGLSCISSORINDEXEDVPROC glScissorIndexedv;
+extern PFNGLDEPTHRANGEARRAYVPROC glDepthRangeArrayv;
+extern PFNGLDEPTHRANGEINDEXEDPROC glDepthRangeIndexed;
+extern PFNGLGETFLOATI_VPROC glGetFloati_v;
+extern PFNGLGETDOUBLEI_VPROC glGetDoublei_v;
+
+// GL_VERSION_4_2
+extern PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glDrawArraysInstancedBaseInstance;
+extern PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glDrawElementsInstancedBaseInstance;
+extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glDrawElementsInstancedBaseVertexBaseInstance;
+extern PFNGLGETINTERNALFORMATIVPROC glGetInternalformativ;
+extern PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glGetActiveAtomicCounterBufferiv;
+extern PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
+extern PFNGLMEMORYBARRIERPROC glMemoryBarrier;
+extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
+extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
+extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
+extern PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glDrawTransformFeedbackInstanced;
+extern PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glDrawTransformFeedbackStreamInstanced;
+
+// GL_VERSION_4_3
+extern PFNGLCLEARBUFFERDATAPROC glClearBufferData;
+extern PFNGLCLEARBUFFERSUBDATAPROC glClearBufferSubData;
+extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
+extern PFNGLDISPATCHCOMPUTEINDIRECTPROC glDispatchComputeIndirect;
+extern PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData;
+extern PFNGLFRAMEBUFFERPARAMETERIPROC glFramebufferParameteri;
+extern PFNGLGETFRAMEBUFFERPARAMETERIVPROC glGetFramebufferParameteriv;
+extern PFNGLGETINTERNALFORMATI64VPROC glGetInternalformati64v;
+extern PFNGLINVALIDATETEXSUBIMAGEPROC glInvalidateTexSubImage;
+extern PFNGLINVALIDATETEXIMAGEPROC glInvalidateTexImage;
+extern PFNGLINVALIDATEBUFFERSUBDATAPROC glInvalidateBufferSubData;
+extern PFNGLINVALIDATEBUFFERDATAPROC glInvalidateBufferData;
+extern PFNGLINVALIDATEFRAMEBUFFERPROC glInvalidateFramebuffer;
+extern PFNGLINVALIDATESUBFRAMEBUFFERPROC glInvalidateSubFramebuffer;
+extern PFNGLMULTIDRAWARRAYSINDIRECTPROC glMultiDrawArraysIndirect;
+extern PFNGLMULTIDRAWELEMENTSINDIRECTPROC glMultiDrawElementsIndirect;
+extern PFNGLGETPROGRAMINTERFACEIVPROC glGetProgramInterfaceiv;
+extern PFNGLGETPROGRAMRESOURCEINDEXPROC glGetProgramResourceIndex;
+extern PFNGLGETPROGRAMRESOURCENAMEPROC glGetProgramResourceName;
+extern PFNGLGETPROGRAMRESOURCEIVPROC glGetProgramResourceiv;
+extern PFNGLGETPROGRAMRESOURCELOCATIONPROC glGetProgramResourceLocation;
+extern PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glGetProgramResourceLocationIndex;
+extern PFNGLSHADERSTORAGEBLOCKBINDINGPROC glShaderStorageBlockBinding;
+extern PFNGLTEXBUFFERRANGEPROC glTexBufferRange;
+extern PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample;
+extern PFNGLTEXSTORAGE3DMULTISAMPLEPROC glTexStorage3DMultisample;
+extern PFNGLTEXTUREVIEWPROC glTextureView;
+extern PFNGLBINDVERTEXBUFFERPROC glBindVertexBuffer;
+extern PFNGLVERTEXATTRIBFORMATPROC glVertexAttribFormat;
+extern PFNGLVERTEXATTRIBIFORMATPROC glVertexAttribIFormat;
+extern PFNGLVERTEXATTRIBLFORMATPROC glVertexAttribLFormat;
+extern PFNGLVERTEXATTRIBBINDINGPROC glVertexAttribBinding;
+extern PFNGLVERTEXBINDINGDIVISORPROC glVertexBindingDivisor;
+extern PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl;
+extern PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert;
+extern PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback;
+extern PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog;
+extern PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup;
+extern PFNGLPOPDEBUGGROUPPROC glPopDebugGroup;
+extern PFNGLOBJECTLABELPROC glObjectLabel;
+extern PFNGLGETOBJECTLABELPROC glGetObjectLabel;
+extern PFNGLOBJECTPTRLABELPROC glObjectPtrLabel;
+extern PFNGLGETOBJECTPTRLABELPROC glGetObjectPtrLabel;
+
+// GL_VERSION_4_4
+extern PFNGLBUFFERSTORAGEPROC glBufferStorage;
+extern PFNGLCLEARTEXIMAGEPROC glClearTexImage;
+extern PFNGLCLEARTEXSUBIMAGEPROC glClearTexSubImage;
+extern PFNGLBINDBUFFERSBASEPROC glBindBuffersBase;
+extern PFNGLBINDBUFFERSRANGEPROC glBindBuffersRange;
+extern PFNGLBINDTEXTURESPROC glBindTextures;
+extern PFNGLBINDSAMPLERSPROC glBindSamplers;
+extern PFNGLBINDIMAGETEXTURESPROC glBindImageTextures;
+extern PFNGLBINDVERTEXBUFFERSPROC glBindVertexBuffers;
+
+// GL_VERSION_4_5
+extern PFNGLCLIPCONTROLPROC glClipControl;
+extern PFNGLCREATETRANSFORMFEEDBACKSPROC glCreateTransformFeedbacks;
+extern PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glTransformFeedbackBufferBase;
+extern PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glTransformFeedbackBufferRange;
+extern PFNGLGETTRANSFORMFEEDBACKIVPROC glGetTransformFeedbackiv;
+extern PFNGLGETTRANSFORMFEEDBACKI_VPROC glGetTransformFeedbacki_v;
+extern PFNGLGETTRANSFORMFEEDBACKI64_VPROC glGetTransformFeedbacki64_v;
+extern PFNGLCREATEBUFFERSPROC glCreateBuffers;
+extern PFNGLNAMEDBUFFERSTORAGEPROC glNamedBufferStorage;
+extern PFNGLNAMEDBUFFERDATAPROC glNamedBufferData;
+extern PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData;
+extern PFNGLCOPYNAMEDBUFFERSUBDATAPROC glCopyNamedBufferSubData;
+extern PFNGLCLEARNAMEDBUFFERDATAPROC glClearNamedBufferData;
+extern PFNGLCLEARNAMEDBUFFERSUBDATAPROC glClearNamedBufferSubData;
+extern PFNGLMAPNAMEDBUFFERPROC glMapNamedBuffer;
+extern PFNGLMAPNAMEDBUFFERRANGEPROC glMapNamedBufferRange;
+extern PFNGLUNMAPNAMEDBUFFERPROC glUnmapNamedBuffer;
+extern PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glFlushMappedNamedBufferRange;
+extern PFNGLGETNAMEDBUFFERPARAMETERIVPROC glGetNamedBufferParameteriv;
+extern PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glGetNamedBufferParameteri64v;
+extern PFNGLGETNAMEDBUFFERPOINTERVPROC glGetNamedBufferPointerv;
+extern PFNGLGETNAMEDBUFFERSUBDATAPROC glGetNamedBufferSubData;
+extern PFNGLCREATEFRAMEBUFFERSPROC glCreateFramebuffers;
+extern PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glNamedFramebufferRenderbuffer;
+extern PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glNamedFramebufferParameteri;
+extern PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glNamedFramebufferTexture;
+extern PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glNamedFramebufferTextureLayer;
+extern PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glNamedFramebufferDrawBuffer;
+extern PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glNamedFramebufferDrawBuffers;
+extern PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glNamedFramebufferReadBuffer;
+extern PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glInvalidateNamedFramebufferData;
+extern PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glInvalidateNamedFramebufferSubData;
+extern PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glClearNamedFramebufferiv;
+extern PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glClearNamedFramebufferuiv;
+extern PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glClearNamedFramebufferfv;
+extern PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glClearNamedFramebufferfi;
+extern PFNGLBLITNAMEDFRAMEBUFFERPROC glBlitNamedFramebuffer;
+extern PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glCheckNamedFramebufferStatus;
+extern PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glGetNamedFramebufferParameteriv;
+extern PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetNamedFramebufferAttachmentParameteriv;
+extern PFNGLCREATERENDERBUFFERSPROC glCreateRenderbuffers;
+extern PFNGLNAMEDRENDERBUFFERSTORAGEPROC glNamedRenderbufferStorage;
+extern PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glNamedRenderbufferStorageMultisample;
+extern PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glGetNamedRenderbufferParameteriv;
+extern PFNGLCREATETEXTURESPROC glCreateTextures;
+extern PFNGLTEXTUREBUFFERPROC glTextureBuffer;
+extern PFNGLTEXTUREBUFFERRANGEPROC glTextureBufferRange;
+extern PFNGLTEXTURESTORAGE1DPROC glTextureStorage1D;
+extern PFNGLTEXTURESTORAGE2DPROC glTextureStorage2D;
+extern PFNGLTEXTURESTORAGE3DPROC glTextureStorage3D;
+extern PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glTextureStorage2DMultisample;
+extern PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glTextureStorage3DMultisample;
+extern PFNGLTEXTURESUBIMAGE1DPROC glTextureSubImage1D;
+extern PFNGLTEXTURESUBIMAGE2DPROC glTextureSubImage2D;
+extern PFNGLTEXTURESUBIMAGE3DPROC glTextureSubImage3D;
+extern PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glCompressedTextureSubImage1D;
+extern PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glCompressedTextureSubImage2D;
+extern PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glCompressedTextureSubImage3D;
+extern PFNGLCOPYTEXTURESUBIMAGE1DPROC glCopyTextureSubImage1D;
+extern PFNGLCOPYTEXTURESUBIMAGE2DPROC glCopyTextureSubImage2D;
+extern PFNGLCOPYTEXTURESUBIMAGE3DPROC glCopyTextureSubImage3D;
+extern PFNGLTEXTUREPARAMETERFPROC glTextureParameterf;
+extern PFNGLTEXTUREPARAMETERFVPROC glTextureParameterfv;
+extern PFNGLTEXTUREPARAMETERIPROC glTextureParameteri;
+extern PFNGLTEXTUREPARAMETERIIVPROC glTextureParameterIiv;
+extern PFNGLTEXTUREPARAMETERIUIVPROC glTextureParameterIuiv;
+extern PFNGLTEXTUREPARAMETERIVPROC glTextureParameteriv;
+extern PFNGLGENERATETEXTUREMIPMAPPROC glGenerateTextureMipmap;
+extern PFNGLBINDTEXTUREUNITPROC glBindTextureUnit;
+extern PFNGLGETTEXTUREIMAGEPROC glGetTextureImage;
+extern PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glGetCompressedTextureImage;
+extern PFNGLGETTEXTURELEVELPARAMETERFVPROC glGetTextureLevelParameterfv;
+extern PFNGLGETTEXTURELEVELPARAMETERIVPROC glGetTextureLevelParameteriv;
+extern PFNGLGETTEXTUREPARAMETERFVPROC glGetTextureParameterfv;
+extern PFNGLGETTEXTUREPARAMETERIIVPROC glGetTextureParameterIiv;
+extern PFNGLGETTEXTUREPARAMETERIUIVPROC glGetTextureParameterIuiv;
+extern PFNGLGETTEXTUREPARAMETERIVPROC glGetTextureParameteriv;
+extern PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays;
+extern PFNGLDISABLEVERTEXARRAYATTRIBPROC glDisableVertexArrayAttrib;
+extern PFNGLENABLEVERTEXARRAYATTRIBPROC glEnableVertexArrayAttrib;
+extern PFNGLVERTEXARRAYELEMENTBUFFERPROC glVertexArrayElementBuffer;
+extern PFNGLVERTEXARRAYVERTEXBUFFERPROC glVertexArrayVertexBuffer;
+extern PFNGLVERTEXARRAYVERTEXBUFFERSPROC glVertexArrayVertexBuffers;
+extern PFNGLVERTEXARRAYATTRIBBINDINGPROC glVertexArrayAttribBinding;
+extern PFNGLVERTEXARRAYATTRIBFORMATPROC glVertexArrayAttribFormat;
+extern PFNGLVERTEXARRAYATTRIBIFORMATPROC glVertexArrayAttribIFormat;
+extern PFNGLVERTEXARRAYATTRIBLFORMATPROC glVertexArrayAttribLFormat;
+extern PFNGLVERTEXARRAYBINDINGDIVISORPROC glVertexArrayBindingDivisor;
+extern PFNGLGETVERTEXARRAYIVPROC glGetVertexArrayiv;
+extern PFNGLGETVERTEXARRAYINDEXEDIVPROC glGetVertexArrayIndexediv;
+extern PFNGLGETVERTEXARRAYINDEXED64IVPROC glGetVertexArrayIndexed64iv;
+extern PFNGLCREATESAMPLERSPROC glCreateSamplers;
+extern PFNGLCREATEPROGRAMPIPELINESPROC glCreateProgramPipelines;
+extern PFNGLCREATEQUERIESPROC glCreateQueries;
+extern PFNGLGETQUERYBUFFEROBJECTI64VPROC glGetQueryBufferObjecti64v;
+extern PFNGLGETQUERYBUFFEROBJECTIVPROC glGetQueryBufferObjectiv;
+extern PFNGLGETQUERYBUFFEROBJECTUI64VPROC glGetQueryBufferObjectui64v;
+extern PFNGLGETQUERYBUFFEROBJECTUIVPROC glGetQueryBufferObjectuiv;
+extern PFNGLMEMORYBARRIERBYREGIONPROC glMemoryBarrierByRegion;
+extern PFNGLGETTEXTURESUBIMAGEPROC glGetTextureSubImage;
+extern PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glGetCompressedTextureSubImage;
+extern PFNGLGETGRAPHICSRESETSTATUSPROC glGetGraphicsResetStatus;
+extern PFNGLGETNCOMPRESSEDTEXIMAGEPROC glGetnCompressedTexImage;
+extern PFNGLGETNTEXIMAGEPROC glGetnTexImage;
+extern PFNGLGETNUNIFORMDVPROC glGetnUniformdv;
+extern PFNGLGETNUNIFORMFVPROC glGetnUniformfv;
+extern PFNGLGETNUNIFORMIVPROC glGetnUniformiv;
+extern PFNGLGETNUNIFORMUIVPROC glGetnUniformuiv;
+extern PFNGLREADNPIXELSPROC glReadnPixels;
+extern PFNGLGETNMAPDVPROC glGetnMapdv;
+extern PFNGLGETNMAPFVPROC glGetnMapfv;
+extern PFNGLGETNMAPIVPROC glGetnMapiv;
+extern PFNGLGETNPIXELMAPFVPROC glGetnPixelMapfv;
+extern PFNGLGETNPIXELMAPUIVPROC glGetnPixelMapuiv;
+extern PFNGLGETNPIXELMAPUSVPROC glGetnPixelMapusv;
+extern PFNGLGETNPOLYGONSTIPPLEPROC glGetnPolygonStipple;
+extern PFNGLGETNCOLORTABLEPROC glGetnColorTable;
+extern PFNGLGETNCONVOLUTIONFILTERPROC glGetnConvolutionFilter;
+extern PFNGLGETNSEPARABLEFILTERPROC glGetnSeparableFilter;
+extern PFNGLGETNHISTOGRAMPROC glGetnHistogram;
+extern PFNGLGETNMINMAXPROC glGetnMinmax;
+extern PFNGLTEXTUREBARRIERPROC glTextureBarrier;
+
+// GL_VERSION_4_6
+extern PFNGLSPECIALIZESHADERPROC glSpecializeShader;
+extern PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glMultiDrawArraysIndirectCount;
+extern PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glMultiDrawElementsIndirectCount;
+extern PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp;
-//GL_EXT_blend_func_separate
-extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
-
-//GL_ARB_framebuffer_object
-extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer;
-extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
-extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
-extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
-extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
-extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv;
-extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
-extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
-extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
-extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
-extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
-extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
-extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
-extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
-extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
-extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
-extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
-extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
-extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
-extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
-
-//GL_ARB_draw_buffers
-extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
-
-//GL_ARB_texture_multisample
-extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
-extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
-extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
-extern PFNGLSAMPLEMASKIPROC glSampleMaski;
-
-//transform feedback (4.0 core)
-extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
-extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
-extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
-extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
-extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
-
-//GL_ARB_debug_output
-extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
-extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
-extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
-extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB;
#elif LL_DARWIN
//----------------------------------------------------------------------------
// LL_DARWIN
+#define GL_GLEXT_LEGACY
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#define GL_EXT_separate_specular_color 1
-#include <OpenGL/glext.h>
+#define GL_GLEXT_PROTOTYPES
+#include "GL/glext.h"
#include "GL/glh_extensions.h"
@@ -607,9 +858,6 @@ extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_A
#define GL_MAX_SAMPLES 0x8D57
#endif
-// GL_ARB_draw_buffers
-extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -694,8 +942,8 @@ extern "C" {
#ifndef GL_ARB_vertex_buffer_object
/* GL types for handling large vertex buffer objects */
-typedef intptr_t GLintptrARB;
-typedef intptr_t GLsizeiptrARB;
+typedef intptr_t GLintptr;
+typedef intptr_t GLsizeiptr;
#endif
@@ -813,22 +1061,8 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
#endif
#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL
- // Tracy uses the following:
- // glGenQueries
- // glGetQueryiv
- // glGetQueryObjectiv
- #define glGenQueries glGenQueriesARB
- #define glGetQueryiv glGetQueryivARB
- #define glGetQueryObjectiv glGetQueryObjectivARB
#include <tracy/TracyOpenGL.hpp>
-
- #define LL_PROFILER_GPU_ZONEC(name,color) TracyGpuZoneC(name,color);
- #define LL_PROFILER_GPU_COLLECT TracyGpuCollect
- #define LL_PROFILER_GPU_CONTEXT TracyGpuContext
-#else
- #define LL_PROFILER_GPU_ZONEC(name,color) (void)name;(void)color;
- #define LL_PROFILER_GPU_COLLECT
- #define LL_PROFILER_GPU_CONTEXT
#endif
+
#endif // LL_LLGLHEADERS_H
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 185c1450c8..27de7070ff 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -37,7 +37,7 @@
#include "OpenGL/OpenGL.h"
#endif
-// Print-print list of shader included source files that are linked together via glAttachObjectARB()
+// Print-print list of shader included source files that are linked together via glAttachShader()
// i.e. On macOS / OSX the AMD GLSL linker will display an error if a varying is left in an undefined state.
#define DEBUG_SHADER_INCLUDES 0
@@ -47,7 +47,7 @@ using std::pair;
using std::make_pair;
using std::string;
-GLhandleARB LLGLSLShader::sCurBoundShader = 0;
+GLuint LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
bool LLGLSLShader::sProfileEnabled = false;
@@ -227,11 +227,10 @@ void LLGLSLShader::stopProfile(U32 count, U32 mode)
void LLGLSLShader::placeProfileQuery()
{
-#if !LL_DARWIN
if (mTimerQuery == 0)
{
- glGenQueriesARB(1, &mSamplesQuery);
- glGenQueriesARB(1, &mTimerQuery);
+ glGenQueries(1, &mSamplesQuery);
+ glGenQueries(1, &mTimerQuery);
}
if (!mTextureStateFetched)
@@ -267,16 +266,14 @@ void LLGLSLShader::placeProfileQuery()
}
- glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery);
- glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
-#endif
+ glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery);
+ glBeginQuery(GL_TIME_ELAPSED, mTimerQuery);
}
void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
{
-#if !LL_DARWIN
- glEndQueryARB(GL_TIME_ELAPSED);
- glEndQueryARB(GL_SAMPLES_PASSED);
+ glEndQuery(GL_TIME_ELAPSED);
+ glEndQuery(GL_SAMPLES_PASSED);
U64 time_elapsed = 0;
glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
@@ -304,7 +301,6 @@ void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
sTotalDrawCalls++;
mDrawCalls++;
-#endif
}
@@ -347,30 +343,37 @@ void LLGLSLShader::unloadInternal()
if (mProgramObject)
{
- GLhandleARB obj[1024];
- GLsizei count;
- glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
+ GLuint obj[1024];
+ GLsizei count = 0;
+ glGetAttachedShaders(mProgramObject, 1024, &count, obj);
+
+ for (GLsizei i = 0; i < count; i++)
+ {
+ glDetachShader(mProgramObject, obj[i]);
+ }
for (GLsizei i = 0; i < count; i++)
{
- glDetachObjectARB(mProgramObject, obj[i]);
- glDeleteObjectARB(obj[i]);
+ if (glIsShader(obj[i]))
+ {
+ glDeleteShader(obj[i]);
+ }
}
- glDeleteObjectARB(mProgramObject);
+ glDeleteProgram(mProgramObject);
mProgramObject = 0;
}
if (mTimerQuery)
{
- glDeleteQueriesARB(1, &mTimerQuery);
+ glDeleteQueries(1, &mTimerQuery);
mTimerQuery = 0;
}
if (mSamplesQuery)
{
- glDeleteQueriesARB(1, &mSamplesQuery);
+ glDeleteQueries(1, &mSamplesQuery);
mSamplesQuery = 0;
}
@@ -401,7 +404,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
llassert_always(!mShaderFiles.empty());
// Create program
- mProgramObject = glCreateProgramObjectARB();
+ mProgramObject = glCreateProgram();
if (mProgramObject == 0)
{
// Shouldn't happen if shader related extensions, like ARB_vertex_shader, exist.
@@ -425,7 +428,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
{
- GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
+ GLuint shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
if (shaderhandle)
{
@@ -452,7 +455,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
#ifdef GL_INTERLEAVED_ATTRIBS
if (varying_count > 0 && varyings)
{
- glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
+ glTransformFeedbackVaryings((GLuint64) mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
}
#endif
@@ -501,24 +504,28 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
unbind();
}
+#ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+ setLabel(mName.c_str());
+#endif
+
return success;
}
#if DEBUG_SHADER_INCLUDES
-void dumpAttachObject( const char *func_name, GLhandleARB program_object, const std::string &object_path )
+void dumpAttachObject( const char *func_name, GLuint program_object, const std::string &object_path )
{
- GLcharARB* info_log;
+ GLchar* info_log;
GLint info_len_expect = 0;
GLint info_len_actual = 0;
- glGetObjectParameterivARB(program_object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_len_expect);
+ glGetShaderiv(program_object, GL_INFO_LOG_LENGTH,, &info_len_expect);
fprintf(stderr, " * %-20s(), log size: %d, %s\n", func_name, info_len_expect, object_path.c_str());
if (info_len_expect > 0)
{
fprintf(stderr, " ========== %s() ========== \n", func_name);
- info_log = new GLcharARB [ info_len_expect ];
- glGetInfoLogARB(program_object, info_len_expect, &info_len_actual, info_log);
+ info_log = new GLchar [ info_len_expect ];
+ glGetProgramInfoLog(program_object, info_len_expect, &info_len_actual, info_log);
fprintf(stderr, "%s\n", info_log);
delete [] info_log;
}
@@ -530,7 +537,7 @@ BOOL LLGLSLShader::attachVertexObject(std::string object_path)
if (LLShaderMgr::instance()->mVertexShaderObjects.count(object_path) > 0)
{
stop_glerror();
- glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mVertexShaderObjects[object_path]);
+ glAttachShader(mProgramObject, LLShaderMgr::instance()->mVertexShaderObjects[object_path]);
#if DEBUG_SHADER_INCLUDES
dumpAttachObject("attachVertexObject", mProgramObject, object_path);
#endif // DEBUG_SHADER_INCLUDES
@@ -549,7 +556,7 @@ BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
if (LLShaderMgr::instance()->mFragmentShaderObjects.count(object_path) > 0)
{
stop_glerror();
- glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mFragmentShaderObjects[object_path]);
+ glAttachShader(mProgramObject, LLShaderMgr::instance()->mFragmentShaderObjects[object_path]);
#if DEBUG_SHADER_INCLUDES
dumpAttachObject("attachFragmentObject", mProgramObject, object_path);
#endif // DEBUG_SHADER_INCLUDES
@@ -563,12 +570,12 @@ BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
}
}
-void LLGLSLShader::attachObject(GLhandleARB object)
+void LLGLSLShader::attachObject(GLuint object)
{
if (object != 0)
{
stop_glerror();
- glAttachObjectARB(mProgramObject, object);
+ glAttachShader(mProgramObject, object);
#if DEBUG_SHADER_INCLUDES
std::string object_path("???");
dumpAttachObject("attachObject", mProgramObject, object_path);
@@ -581,7 +588,7 @@ void LLGLSLShader::attachObject(GLhandleARB object)
}
}
-void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
+void LLGLSLShader::attachObjects(GLuint* objects, S32 count)
{
for (S32 i = 0; i < count; i++)
{
@@ -597,7 +604,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
- glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name);
+ glBindAttribLocation(mProgramObject, i, (const GLchar *) name);
}
//link the program
@@ -620,7 +627,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
- S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name);
+ S32 index = glGetAttribLocation(mProgramObject, (const GLchar *)name);
if (index != -1)
{
#if LL_RELEASE_WITH_DEBUG_INFO
@@ -637,7 +644,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
for (U32 i = 0; i < numAttributes; i++)
{
const char* name = (*attributes)[i].String().c_str();
- S32 index = glGetAttribLocationARB(mProgramObject, name);
+ S32 index = glGetAttribLocation(mProgramObject, name);
if (index != -1)
{
mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index;
@@ -668,8 +675,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
name[0] = 0;
- glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
-#if !LL_DARWIN
+ glGetActiveUniform(mProgramObject, index, 1024, &length, &size, &type, (GLchar *)name);
if (size > 0)
{
switch(type)
@@ -711,9 +717,8 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
}
mTotalUniformSize += size;
}
-#endif
- S32 location = glGetUniformLocationARB(mProgramObject, name);
+ S32 location = glGetUniformLocation(mProgramObject, name);
if (location != -1)
{
//chop off "[0]" so we can always access the first element
@@ -738,7 +743,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
{
//found it
mUniform[i] = location;
- mTexture[i] = mapUniformTextureChannel(location, type);
+ mTexture[i] = mapUniformTextureChannel(location, type, size);
return;
}
}
@@ -752,7 +757,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
{
//found it
mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
- mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type);
+ mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type, size);
return;
}
}
@@ -775,16 +780,38 @@ void LLGLSLShader::removePermutation(std::string name)
mDefines[name].erase();
}
-GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
+GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type, GLint size)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
- type == GL_SAMPLER_2D_MULTISAMPLE)
+ if ((type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_RECT_SHADOW) ||
+ type == GL_SAMPLER_2D_MULTISAMPLE ||
+ type == GL_SAMPLER_CUBE_MAP_ARRAY)
{ //this here is a texture
- glUniform1iARB(location, mActiveTextureChannels);
- LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
- return mActiveTextureChannels++;
+ GLint ret = mActiveTextureChannels;
+ if (size == 1)
+ {
+ glUniform1i(location, mActiveTextureChannels);
+ LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
+ mActiveTextureChannels++;
+ }
+ else
+ {
+ //is array of textures, make sequential after this texture
+ GLint channel[32]; // <=== only support up to 32 texture channels
+ llassert(size <= 32);
+ size = llmin(size, 32);
+ for (int i = 0; i < size; ++i)
+ {
+ channel[i] = mActiveTextureChannels++;
+ }
+ glUniform1iv(location, size, channel);
+ LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " <<
+ (mActiveTextureChannels-size) << " through " << (mActiveTextureChannels-1) << LL_ENDL;
+ }
+
+ llassert(mActiveTextureChannels <= 32); // too many textures (probably)
+ return ret;
}
return -1;
}
@@ -811,7 +838,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
//get the number of active uniforms
GLint activeCount;
- glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
+ glGetProgramiv(mProgramObject, GL_ACTIVE_UNIFORMS, &activeCount);
//........................................................................................................................................
//........................................................................................
@@ -832,14 +859,18 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
As example where this situation appear see: "Deferred Material Shader 28/29/30/31"
And tickets: MAINT-4165, MAINT-4839, MAINT-3568, MAINT-6437
+
+ --- davep TODO -- pretty sure the entire block here is superstitious and that the uniform index has nothing to do with the texture channel
+ texture channel should follow the uniform VALUE
*/
- S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
- S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");
- S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
- S32 altDiffuseMap = glGetUniformLocationARB(mProgramObject, "altDiffuseMap");
- S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
+ S32 diffuseMap = glGetUniformLocation(mProgramObject, "diffuseMap");
+ S32 specularMap = glGetUniformLocation(mProgramObject, "specularMap");
+ S32 bumpMap = glGetUniformLocation(mProgramObject, "bumpMap");
+ S32 altDiffuseMap = glGetUniformLocation(mProgramObject, "altDiffuseMap");
+ S32 environmentMap = glGetUniformLocation(mProgramObject, "environmentMap");
+ S32 reflectionMap = glGetUniformLocation(mProgramObject, "reflectionMap");
std::set<S32> skip_index;
@@ -856,7 +887,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
{
name[0] = '\0';
- glGetActiveUniformARB(mProgramObject, i, 1024, &length, &size, &type, (GLcharARB *)name);
+ glGetActiveUniform(mProgramObject, i, 1024, &length, &size, &type, (GLchar *)name);
if (-1 == diffuseMap && std::string(name) == "diffuseMap")
{
@@ -882,6 +913,12 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
continue;
}
+ if (-1 == reflectionMap && std::string(name) == "reflectionMap")
+ {
+ reflectionMap = i;
+ continue;
+ }
+
if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
{
altDiffuseMap = i;
@@ -892,8 +929,9 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
+ bool refLessDiff = reflectionMap < diffuseMap && -1 != reflectionMap;
- if (specularDiff || bumpLessDiff || envLessDiff)
+ if (specularDiff || bumpLessDiff || envLessDiff || refLessDiff)
{
mapUniform(diffuseMap, uniforms);
skip_index.insert(diffuseMap);
@@ -912,6 +950,11 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
mapUniform(environmentMap, uniforms);
skip_index.insert(environmentMap);
}
+
+ if (-1 != reflectionMap) {
+ mapUniform(reflectionMap, uniforms);
+ skip_index.insert(reflectionMap);
+ }
}
}
@@ -927,6 +970,17 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
}
//........................................................................................................................................
+ if (mFeatures.hasReflectionProbes) // Set up block binding, in a way supported by Apple (rather than binding = 1 in .glsl).
+ { // See slide 35 and more of https://docs.huihoo.com/apple/wwdc/2011/session_420__advances_in_opengl_for_mac_os_x_lion.pdf
+ static const GLuint BLOCKBINDING = 1; //picked by us
+ //Get the index, similar to a uniform location
+ GLuint UBOBlockIndex = glGetUniformBlockIndex(mProgramObject, "ReflectionProbes");
+ if (UBOBlockIndex != GL_INVALID_INDEX)
+ {
+ //Set this index to a binding index
+ glUniformBlockBinding(mProgramObject, UBOBlockIndex, BLOCKBINDING);
+ }
+ }
unbind();
LL_DEBUGS("ShaderUniform") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
@@ -957,7 +1011,7 @@ void LLGLSLShader::bind()
if (sCurBoundShader != mProgramObject) // Don't re-bind current shader
{
LLVertexBuffer::unbind();
- glUseProgramObjectARB(mProgramObject);
+ glUseProgram(mProgramObject);
sCurBoundShader = mProgramObject;
sCurBoundShaderPtr = this;
}
@@ -989,7 +1043,7 @@ void LLGLSLShader::unbind()
gGL.flush();
stop_glerror();
LLVertexBuffer::unbind();
- glUseProgramObjectARB(0);
+ glUseProgram(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
stop_glerror();
@@ -1000,7 +1054,7 @@ void LLGLSLShader::bindNoShader(void)
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
LLVertexBuffer::unbind();
- glUseProgramObjectARB(0);
+ glUseProgram(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
}
@@ -1130,7 +1184,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
const auto& iter = mValue.find(mUniform[index]);
if (iter == mValue.end() || iter->second.mV[0] != x)
{
- glUniform1iARB(mUniform[index], x);
+ glUniform1i(mUniform[index], x);
mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
}
}
@@ -1153,7 +1207,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
const auto& iter = mValue.find(mUniform[index]);
if (iter == mValue.end() || iter->second.mV[0] != x)
{
- glUniform1fARB(mUniform[index], x);
+ glUniform1f(mUniform[index], x);
mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
}
}
@@ -1176,7 +1230,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
LLVector4 vec(x,y,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform2fARB(mUniform[index], x, y);
+ glUniform2f(mUniform[index], x, y);
mValue[mUniform[index]] = vec;
}
}
@@ -1199,7 +1253,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
LLVector4 vec(x,y,z,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform3fARB(mUniform[index], x, y, z);
+ glUniform3f(mUniform[index], x, y, z);
mValue[mUniform[index]] = vec;
}
}
@@ -1222,7 +1276,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
LLVector4 vec(x,y,z,w);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform4fARB(mUniform[index], x, y, z, w);
+ glUniform4f(mUniform[index], x, y, z, w);
mValue[mUniform[index]] = vec;
}
}
@@ -1245,13 +1299,37 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- glUniform1ivARB(mUniform[index], count, v);
+ glUniform1iv(mUniform[index], count, v);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
+}
+
+void LLGLSLShader::uniform4iv(U32 index, U32 count, const GLint* v)
+{
+ if (mProgramObject)
+ {
+ if (mUniform.size() <= index)
+ {
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ const auto& iter = mValue.find(mUniform[index]);
+ LLVector4 vec(v[0], v[1], v[2], v[3]);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
+ {
+ glUniform1iv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
}
}
+
void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
{
if (mProgramObject)
@@ -1268,7 +1346,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- glUniform1fvARB(mUniform[index], count, v);
+ glUniform1fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
@@ -1291,7 +1369,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
LLVector4 vec(v[0],v[1],0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- glUniform2fvARB(mUniform[index], count, v);
+ glUniform2fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
@@ -1314,7 +1392,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
LLVector4 vec(v[0],v[1],v[2],0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- glUniform3fvARB(mUniform[index], count, v);
+ glUniform3fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
@@ -1338,7 +1416,7 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- glUniform4fvARB(mUniform[index], count, v);
+ glUniform4fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
@@ -1357,7 +1435,7 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c
if (mUniform[index] >= 0)
{
- glUniformMatrix2fvARB(mUniform[index], count, transpose, v);
+ glUniformMatrix2fv(mUniform[index], count, transpose, v);
}
}
}
@@ -1374,7 +1452,7 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
if (mUniform[index] >= 0)
{
- glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
+ glUniformMatrix3fv(mUniform[index], count, transpose, v);
}
}
}
@@ -1410,7 +1488,7 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
if (mUniform[index] >= 0)
{
- glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
+ glUniformMatrix4fv(mUniform[index], count, transpose, v);
}
}
}
@@ -1428,7 +1506,7 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
if (gDebugGL)
{
stop_glerror();
- if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
+ if (iter->second != glGetUniformLocation(mProgramObject, uniform.String().c_str()))
{
LL_ERRS() << "Uniform does not match." << LL_ENDL;
}
@@ -1483,7 +1561,41 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
LLVector4 vec(v,0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform1iARB(location, v);
+ glUniform1i(location, v);
+ mValue[location] = vec;
+ }
+ }
+}
+
+void LLGLSLShader::uniform1iv(const LLStaticHashedString& uniform, U32 count, const GLint* v)
+{
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ LLVector4 vec(v[0], 0, 0, 0);
+ const auto& iter = mValue.find(location);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ glUniform1iv(location, count, v);
+ mValue[location] = vec;
+ }
+ }
+}
+
+void LLGLSLShader::uniform4iv(const LLStaticHashedString& uniform, U32 count, const GLint* v)
+{
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ LLVector4 vec(v[0], v[1], v[2], v[3]);
+ const auto& iter = mValue.find(location);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ glUniform4iv(location, count, v);
mValue[location] = vec;
}
}
@@ -1499,7 +1611,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint
LLVector4 vec(i,j,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform2iARB(location, i, j);
+ glUniform2i(location, i, j);
mValue[location] = vec;
}
}
@@ -1516,7 +1628,7 @@ void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
LLVector4 vec(v,0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform1fARB(location, v);
+ glUniform1f(location, v);
mValue[location] = vec;
}
}
@@ -1532,7 +1644,7 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf
LLVector4 vec(x,y,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform2fARB(location, x,y);
+ glUniform2f(location, x,y);
mValue[location] = vec;
}
}
@@ -1549,7 +1661,7 @@ void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLf
LLVector4 vec(x,y,z,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform3fARB(location, x,y,z);
+ glUniform3f(location, x,y,z);
mValue[location] = vec;
}
}
@@ -1565,7 +1677,7 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- glUniform1fvARB(location, count, v);
+ glUniform1fv(location, count, v);
mValue[location] = vec;
}
}
@@ -1581,7 +1693,7 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co
LLVector4 vec(v[0],v[1],0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- glUniform2fvARB(location, count, v);
+ glUniform2fv(location, count, v);
mValue[location] = vec;
}
}
@@ -1597,7 +1709,7 @@ void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, co
LLVector4 vec(v[0],v[1],v[2],0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- glUniform3fvARB(location, count, v);
+ glUniform3fv(location, count, v);
mValue[location] = vec;
}
}
@@ -1614,7 +1726,7 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- glUniform4fvARB(location, count, v);
+ glUniform4fv(location, count, v);
mValue[location] = vec;
}
}
@@ -1627,7 +1739,7 @@ void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 cou
if (location >= 0)
{
stop_glerror();
- glUniformMatrix4fvARB(location, count, transpose, v);
+ glUniformMatrix4fv(location, count, transpose, v);
stop_glerror();
}
}
@@ -1637,7 +1749,7 @@ void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GL
{
if (mAttribute[index] > 0)
{
- glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
+ glVertexAttrib4f(mAttribute[index], x, y, z, w);
}
}
@@ -1645,7 +1757,7 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
{
if (mAttribute[index] > 0)
{
- glVertexAttrib4fvARB(mAttribute[index], v);
+ glVertexAttrib4fv(mAttribute[index], v);
}
}
@@ -1678,3 +1790,10 @@ void LLShaderUniforms::apply(LLGLSLShader* shader)
shader->uniform3fv(uniform.mUniform, 1, uniform.mValue.mV);
}
}
+
+#ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+void LLGLSLShader::setLabel(const char* label) {
+ LL_LABEL_OBJECT_GL(GL_PROGRAM, mProgramObject, strlen(label), label);
+}
+
+#endif
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 85e83dbcb9..3401da832e 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -52,12 +52,13 @@ public:
bool hasShadows;
bool hasAmbientOcclusion;
bool hasSrgb;
- bool encodesNormal;
+ bool encodesNormal; // include: shaders\class1\environment\encodeNormF.glsl
bool isDeferred;
bool hasIndirect;
S32 mIndexedTextureChannels;
bool disableTextureIndex;
bool hasAlphaMask;
+ bool hasReflectionProbes = false;
bool attachNothing;
// char numLights;
@@ -117,6 +118,11 @@ public:
mVector3s.push_back({ index, value });
}
+ void uniform3fv(S32 index, const F32* value)
+ {
+ mVector3s.push_back({ index, LLVector3(value) });
+ }
+
void apply(LLGLSLShader* shader);
@@ -145,7 +151,7 @@ public:
LLGLSLShader();
~LLGLSLShader();
- static GLhandleARB sCurBoundShader;
+ static GLuint sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
@@ -167,8 +173,8 @@ public:
const char** varyings = NULL);
BOOL attachFragmentObject(std::string object);
BOOL attachVertexObject(std::string object);
- void attachObject(GLhandleARB object);
- void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
+ void attachObject(GLuint object);
+ void attachObjects(GLuint* objects = NULL, S32 count = 0);
BOOL mapAttributes(const std::vector<LLStaticHashedString> * attributes);
BOOL mapUniforms(const std::vector<LLStaticHashedString> *);
void mapUniform(GLint index, const std::vector<LLStaticHashedString> *);
@@ -178,6 +184,7 @@ public:
void uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z);
void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void uniform1iv(U32 index, U32 count, const GLint* i);
+ void uniform4iv(U32 index, U32 count, const GLint* i);
void uniform1fv(U32 index, U32 count, const GLfloat* v);
void uniform2fv(U32 index, U32 count, const GLfloat* v);
void uniform3fv(U32 index, U32 count, const GLfloat* v);
@@ -188,6 +195,8 @@ public:
void uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
void uniform1i(const LLStaticHashedString& uniform, GLint i);
+ void uniform1iv(const LLStaticHashedString& uniform, U32 count, const GLint* v);
+ void uniform4iv(const LLStaticHashedString& uniform, U32 count, const GLint* v);
void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
@@ -207,7 +216,7 @@ public:
GLint getUniformLocation(U32 index);
GLint getAttribLocation(U32 attrib);
- GLint mapUniformTextureChannel(GLint location, GLenum type);
+ GLint mapUniformTextureChannel(GLint location, GLenum type, GLint size);
void clearPermutations();
void addPermutation(std::string name, std::string value);
@@ -239,7 +248,7 @@ public:
U32 mMatHash[LLRender::NUM_MATRIX_MODES];
U32 mLightHash;
- GLhandleARB mProgramObject;
+ GLuint mProgramObject;
#if LL_RELEASE_WITH_DEBUG_INFO
struct attr_name
{
@@ -290,6 +299,10 @@ public:
// this pointer should be set to whichever shader represents this shader's rigged variant
LLGLSLShader* mRiggedVariant = nullptr;
+ #ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+ void setLabel(const char* label);
+ #endif
+
private:
void unloadInternal();
};
@@ -301,5 +314,10 @@ extern LLGLSLShader gSolidColorProgram;
//Alpha mask shader (declared here so llappearance can access properly)
extern LLGLSLShader gAlphaMaskProgram;
+#ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+#define LL_SET_SHADER_LABEL(shader) shader.setLabel(#shader)
+#else
+#define LL_SET_SHADER_LABEL(shader, label)
+#endif
#endif
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index a4924eba14..27ab142925 100644
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -75,7 +75,7 @@ public:
mLineStipple(GL_LINE_STIPPLE),
mNormalize(GL_NORMALIZE),
mPolygonSmooth(GL_POLYGON_SMOOTH),
- mGLMultisample(GL_MULTISAMPLE_ARB)
+ mGLMultisample(GL_MULTISAMPLE)
{ }
};
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index ae10142e7a..d16757d0ed 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -54,7 +54,6 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f;
U32 wpo2(U32 i);
-#if LL_DARWIN
// texture memory accounting (for OS X)
static LLMutex sTexMemMutex;
static std::unordered_map<U32, U32> sTextureAllocs;
@@ -119,22 +118,6 @@ U64 LLImageGL::getTextureBytesAllocated()
return sTextureBytes;
}
-#else
-
-#define alloc_tex_image(width, height, pixformat) (void) width; (void) height; (void) pixformat;
-#define free_tex_image(texName) (void) texName;
-#define free_tex_images(count, texNames) (void) count; (void) texNames;
-#define free_cur_tex_image()
-
-// static
-U64 LLImageGL::getTextureBytesAllocated()
-{
- // UNIMPLEMENTED OUTSIDE OF OS X, DO NOT CALL
- llassert(false);
- return 0;
-}
-#endif
-
//statics
U32 LLImageGL::sUniqueCount = 0;
@@ -369,7 +352,7 @@ void LLImageGL::updateStats(F32 current_time)
//static
void LLImageGL::destroyGL(BOOL save_state)
{
- for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++)
+ for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++)
{
gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -537,7 +520,6 @@ void LLImageGL::init(BOOL usemipmaps)
mPickMaskHeight = 0;
mUseMipMaps = usemipmaps;
mHasExplicitFormat = FALSE;
- mAutoGenMips = FALSE;
mIsMask = FALSE;
mNeedsAlphaAndPickMask = TRUE ;
@@ -811,7 +793,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
if (is_compressed)
{
S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
- glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
+ glCompressedTexImage2D(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
stop_glerror();
}
else
@@ -882,6 +864,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
if (LLRender::sGLCoreProfile)
{
+ LL_PROFILE_GPU_ZONE("generate mip map");
glGenerateMipmap(mTarget);
}
stop_glerror();
@@ -1006,7 +989,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
if (is_compressed)
{
S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
- glCompressedTexImage2DARB(mTarget, 0, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
+ glCompressedTexImage2D(mTarget, 0, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
stop_glerror();
}
else
@@ -1085,30 +1068,12 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
mFormatType = GL_UNSIGNED_BYTE;
break;
case 3:
-#if USE_SRGB_DECODE
- if (gGLManager.mHasTexturesRGBDecode)
- {
- mFormatInternal = GL_SRGB8;
- }
- else
-#endif
- {
- mFormatInternal = GL_RGB8;
- }
+ mFormatInternal = GL_RGB8;
mFormatPrimary = GL_RGB;
mFormatType = GL_UNSIGNED_BYTE;
break;
case 4:
-#if USE_SRGB_DECODE
- if (gGLManager.mHasTexturesRGBDecode)
- {
- mFormatInternal = GL_SRGB8_ALPHA8;
- }
- else
-#endif
- {
- mFormatInternal = GL_RGBA8;
- }
+ mFormatInternal = GL_RGBA8;
mFormatPrimary = GL_RGBA;
mFormatType = GL_UNSIGNED_BYTE;
break;
@@ -1319,7 +1284,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@@ -1339,7 +1309,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@@ -1362,7 +1337,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@@ -1541,30 +1521,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
mFormatType = GL_UNSIGNED_BYTE;
break;
case 3:
- #if USE_SRGB_DECODE
- if (gGLManager.mHasTexturesRGBDecode)
- {
- mFormatInternal = GL_SRGB8;
- }
- else
- #endif
- {
- mFormatInternal = GL_RGB8;
- }
+ mFormatInternal = GL_RGB8;
mFormatPrimary = GL_RGB;
mFormatType = GL_UNSIGNED_BYTE;
break;
case 4:
- #if USE_SRGB_DECODE
- if (gGLManager.mHasTexturesRGBDecode)
- {
- mFormatInternal = GL_SRGB8_ALPHA8;
- }
- else
- #endif
- {
- mFormatInternal = GL_RGBA8;
- }
+ mFormatInternal = GL_RGBA8;
mFormatPrimary = GL_RGBA;
mFormatType = GL_UNSIGNED_BYTE;
break;
@@ -1593,6 +1555,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
// Call with void data, vmem is allocated but unitialized
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ LL_PROFILE_GPU_ZONE("createGLTexture");
checkActiveThread();
bool main_thread = on_main_thread();
@@ -1652,7 +1615,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
if (mUseMipMaps)
{
- mAutoGenMips = gGLManager.mHasMipMapGeneration;
+ mAutoGenMips = true;
}
mCurrentDiscardLevel = discard_level;
@@ -1709,44 +1672,37 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name)
{
LL_PROFILE_ZONE_NAMED("cglt - sync");
- if (gGLManager.mHasSync)
+ if (gGLManager.mIsNVIDIA)
{
- if (gGLManager.mIsNVIDIA)
- {
- // wait for texture upload to finish before notifying main thread
- // upload is complete
- auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
- glFlush();
- glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
- glDeleteSync(sync);
- }
- else
- {
- // post a sync to the main thread (will execute before tex name swap lambda below)
- // glFlush calls here are partly superstitious and partly backed by observation
- // on AMD hardware
- glFlush();
- auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
- glFlush();
- LL::WorkQueue::postMaybe(
- mMainQueue,
- [=]()
- {
- LL_PROFILE_ZONE_NAMED("cglt - wait sync");
- {
- LL_PROFILE_ZONE_NAMED("glWaitSync");
- glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
- }
- {
- LL_PROFILE_ZONE_NAMED("glDeleteSync");
- glDeleteSync(sync);
- }
- });
- }
+ // wait for texture upload to finish before notifying main thread
+ // upload is complete
+ auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ glFlush();
+ glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
+ glDeleteSync(sync);
}
else
{
- glFinish();
+ // post a sync to the main thread (will execute before tex name swap lambda below)
+ // glFlush calls here are partly superstitious and partly backed by observation
+ // on AMD hardware
+ glFlush();
+ auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ glFlush();
+ LL::WorkQueue::postMaybe(
+ mMainQueue,
+ [=]()
+ {
+ LL_PROFILE_ZONE_NAMED("cglt - wait sync");
+ {
+ LL_PROFILE_ZONE_NAMED("glWaitSync");
+ glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
+ }
+ {
+ LL_PROFILE_ZONE_NAMED("glDeleteSync");
+ glDeleteSync(sync);
+ }
+ });
}
}
@@ -1759,8 +1715,11 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name)
syncTexName(new_tex_name);
unref();
});
+
+ LL_PROFILER_GPU_COLLECT;
}
+
void LLImageGL::syncTexName(LLGLuint texname)
{
if (texname != 0)
@@ -1850,7 +1809,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
return FALSE ;
}
- glGetCompressedTexImageARB(mTarget, gl_discard, (GLvoid*)(imageraw->getData()));
+ glGetCompressedTexImage(mTarget, gl_discard, (GLvoid*)(imageraw->getData()));
//stop_glerror();
}
else
@@ -2462,7 +2421,7 @@ void LLImageGLThread::run()
// We must perform setup on this thread before actually servicing our
// WorkQueue, likewise cleanup afterwards.
mWindow->makeContextCurrent(mContext);
- gGL.init();
+ gGL.init(false);
ThreadPool::run();
gGL.shutdown();
mWindow->destroySharedContext(mContext);
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 619421e68a..bbd024abd9 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -53,7 +53,10 @@ class LLImageGL : public LLRefCount
friend class LLTexUnit;
public:
- // For OS X use only -- get an estimate of how many bytes have been allocated in vram for textures
+ // Get an estimate of how many bytes have been allocated in vram for textures.
+ // Does not include mipmaps.
+ // NOTE: multiplying this number by two gives a good estimate for total
+ // video memory usage based on testing in lagland against an NVIDIA GPU.
static U64 getTextureBytesAllocated();
// These 2 functions replace glGenTextures() and glDeleteTextures()
@@ -162,7 +165,7 @@ public:
BOOL getUseMipMaps() const { return mUseMipMaps; }
void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
-
+ void setHasMipMaps(BOOL hasmips) { mHasMipMaps = hasmips; }
void updatePickMask(S32 width, S32 height, const U8* data_in);
BOOL getMask(const LLVector2 &tc);
@@ -216,7 +219,7 @@ private:
U16 mPickMaskHeight;
S8 mUseMipMaps;
BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents)
- S8 mAutoGenMips;
+ bool mAutoGenMips = false;
BOOL mIsMask;
BOOL mNeedsAlphaAndPickMask;
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index b6ea5aa7f1..74154e5676 100644
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -239,17 +239,17 @@ void LLPostProcess::applyColorFilterShader(void)
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture);
getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject);
- glUniform1iARB(colorFilterUniforms["RenderTexture"], 0);
- glUniform1fARB(colorFilterUniforms["brightness"], tweaks.getBrightness());
- glUniform1fARB(colorFilterUniforms["contrast"], tweaks.getContrast());
+ glUniform1i(colorFilterUniforms["RenderTexture"], 0);
+ glUniform1f(colorFilterUniforms["brightness"], tweaks.getBrightness());
+ glUniform1f(colorFilterUniforms["contrast"], tweaks.getContrast());
float baseI = (tweaks.getContrastBaseR() + tweaks.getContrastBaseG() + tweaks.getContrastBaseB()) / 3.0f;
baseI = tweaks.getContrastBaseIntensity() / ((baseI < 0.001f) ? 0.001f : baseI);
float baseR = tweaks.getContrastBaseR() * baseI;
float baseG = tweaks.getContrastBaseG() * baseI;
float baseB = tweaks.getContrastBaseB() * baseI;
- glUniform3fARB(colorFilterUniforms["contrastBase"], baseR, baseG, baseB);
- glUniform1fARB(colorFilterUniforms["saturation"], tweaks.getSaturation());
- glUniform3fARB(colorFilterUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B);
+ glUniform3f(colorFilterUniforms["contrastBase"], baseR, baseG, baseB);
+ glUniform1f(colorFilterUniforms["saturation"], tweaks.getSaturation());
+ glUniform3f(colorFilterUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B);
LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_REPLACE);
@@ -282,22 +282,22 @@ void LLPostProcess::applyNightVisionShader(void)
getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture);
- glUniform1iARB(nightVisionUniforms["RenderTexture"], 0);
+ glUniform1i(nightVisionUniforms["RenderTexture"], 0);
gGL.getTexUnit(1)->activate();
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->bindManual(LLTexUnit::TT_TEXTURE, noiseTexture);
- glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1);
+ glUniform1i(nightVisionUniforms["NoiseTexture"], 1);
- glUniform1fARB(nightVisionUniforms["brightMult"], tweaks.getBrightMult());
- glUniform1fARB(nightVisionUniforms["noiseStrength"], tweaks.getNoiseStrength());
+ glUniform1f(nightVisionUniforms["brightMult"], tweaks.getBrightMult());
+ glUniform1f(nightVisionUniforms["noiseStrength"], tweaks.getNoiseStrength());
noiseTextureScale = 0.01f + ((101.f - tweaks.getNoiseSize()) / 100.f);
noiseTextureScale *= (screenH / NOISE_SIZE);
- glUniform3fARB(nightVisionUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B);
+ glUniform3f(nightVisionUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B);
LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_REPLACE);
@@ -345,12 +345,12 @@ void LLPostProcess::createBloomShader(void)
bloomBlurUniforms[sBlurWidth] = 0;
}
-void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog)
+void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLuint & prog)
{
/// Find uniform locations and insert into map
glslUniforms::iterator i;
for (i = uniforms.begin(); i != uniforms.end(); ++i){
- i->second = glGetUniformLocationARB(prog, i->first.String().c_str());
+ i->second = glGetUniformLocation(prog, i->first.String().c_str());
}
}
@@ -391,7 +391,7 @@ void LLPostProcess::doEffects(void)
void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height)
{
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture);
- glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0);
+ glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, width, height, 0);
}
void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type)
@@ -410,60 +410,60 @@ void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadT
glBegin(GL_QUADS);
if (type != QUAD_BLOOM_EXTRACT){
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height);
+ glMultiTexCoord2f(GL_TEXTURE0, 0.f, (GLfloat) height);
} else {
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height * 2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0, 0.f, (GLfloat) height * 2.0f);
}
if (type == QUAD_NOISE){
- glMultiTexCoord2fARB(GL_TEXTURE1_ARB,
+ glMultiTexCoord2f(GL_TEXTURE1,
noiseX,
noiseTextureScale + noiseY);
} else if (type == QUAD_BLOOM_COMBINE){
- glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, (GLfloat) height * 0.5f);
+ glMultiTexCoord2f(GL_TEXTURE1, 0.f, (GLfloat) height * 0.5f);
}
glVertex2f(0.f, (GLfloat) screenH - height);
if (type != QUAD_BLOOM_EXTRACT){
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f);
+ glMultiTexCoord2f(GL_TEXTURE0, 0.f, 0.f);
} else {
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f);
+ glMultiTexCoord2f(GL_TEXTURE0, 0.f, 0.f);
}
if (type == QUAD_NOISE){
- glMultiTexCoord2fARB(GL_TEXTURE1_ARB,
+ glMultiTexCoord2f(GL_TEXTURE1,
noiseX,
noiseY);
} else if (type == QUAD_BLOOM_COMBINE){
- glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, 0.f);
+ glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f);
}
glVertex2f(0.f, (GLfloat) height + (screenH - height));
if (type != QUAD_BLOOM_EXTRACT){
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, 0.f);
+ glMultiTexCoord2f(GL_TEXTURE0, (GLfloat) width, 0.f);
} else {
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, 0.f);
+ glMultiTexCoord2f(GL_TEXTURE0, (GLfloat) width * 2.0f, 0.f);
}
if (type == QUAD_NOISE){
- glMultiTexCoord2fARB(GL_TEXTURE1_ARB,
+ glMultiTexCoord2f(GL_TEXTURE1,
screenRatio * noiseTextureScale + noiseX,
noiseY);
} else if (type == QUAD_BLOOM_COMBINE){
- glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, 0.f);
+ glMultiTexCoord2f(GL_TEXTURE1, (GLfloat) width * 0.5f, 0.f);
}
glVertex2f((GLfloat) width, (GLfloat) height + (screenH - height));
if (type != QUAD_BLOOM_EXTRACT){
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, (GLfloat) height);
+ glMultiTexCoord2f(GL_TEXTURE0, (GLfloat) width, (GLfloat) height);
} else {
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, (GLfloat) height * 2.0f);
+ glMultiTexCoord2f(GL_TEXTURE0, (GLfloat) width * 2.0f, (GLfloat) height * 2.0f);
}
if (type == QUAD_NOISE){
- glMultiTexCoord2fARB(GL_TEXTURE1_ARB,
+ glMultiTexCoord2f(GL_TEXTURE1,
screenRatio * noiseTextureScale + noiseX,
noiseTextureScale + noiseY);
} else if (type == QUAD_BLOOM_COMBINE){
- glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, (GLfloat) height * 0.5f);
+ glMultiTexCoord2f(GL_TEXTURE1, (GLfloat) width * 0.5f, (GLfloat) height * 0.5f);
}
glVertex2f((GLfloat) width, (GLfloat) screenH - height);
glEnd();
@@ -503,7 +503,7 @@ void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int wi
if(texture->createGLTexture())
{
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture->getTexName());
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0,
+ glTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
@@ -557,7 +557,7 @@ bool LLPostProcess::checkError(void)
return retCode;
}
-void LLPostProcess::checkShaderError(GLhandleARB shader)
+void LLPostProcess::checkShaderError(GLuint shader)
{
GLint infologLength = 0;
GLint charsWritten = 0;
@@ -565,7 +565,7 @@ void LLPostProcess::checkShaderError(GLhandleARB shader)
checkError(); // Check for OpenGL errors
- glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
checkError(); // Check for OpenGL errors
@@ -577,7 +577,7 @@ void LLPostProcess::checkShaderError(GLhandleARB shader)
/// Could not allocate infolog buffer
return;
}
- glGetInfoLogARB(shader, infologLength, &charsWritten, infoLog);
+ glGetProgramInfoLog(shader, infologLength, &charsWritten, infoLog);
// shaderErrorLog << (char *) infoLog << std::endl;
mShaderErrorString = (char *) infoLog;
free(infoLog);
diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h
index ce17b6693d..bdfc632831 100644
--- a/indra/llrender/llpostprocess.h
+++ b/indra/llrender/llpostprocess.h
@@ -249,12 +249,12 @@ private:
void applyColorFilterShader(void);
/// OpenGL Helper Functions
- void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog);
+ void getShaderUniforms(glslUniforms & uniforms, GLuint & prog);
void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height);
void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height);
void createNoiseTexture(LLPointer<LLImageGL>& texture);
bool checkError(void);
- void checkShaderError(GLhandleARB shader);
+ void checkShaderError(GLuint shader);
void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type);
void viewOrthogonal(unsigned int width, unsigned int height);
void changeOrthogonal(unsigned int width, unsigned int height);
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 15c509dbfb..39e3a0243c 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -69,8 +69,9 @@ static const U32 LL_NUM_LIGHT_UNITS = 8;
static const GLenum sGLTextureType[] =
{
GL_TEXTURE_2D,
- GL_TEXTURE_RECTANGLE_ARB,
- GL_TEXTURE_CUBE_MAP_ARB,
+ GL_TEXTURE_RECTANGLE,
+ GL_TEXTURE_CUBE_MAP,
+ GL_TEXTURE_CUBE_MAP_ARRAY,
GL_TEXTURE_2D_MULTISAMPLE,
GL_TEXTURE_3D
};
@@ -122,7 +123,7 @@ void LLTexUnit::refreshState(void)
gGL.flush();
- glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
+ glActiveTexture(GL_TEXTURE0 + mIndex);
if (mCurrTexType != TT_NONE)
{
@@ -143,7 +144,7 @@ void LLTexUnit::activate(void)
if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
{
gGL.flush();
- glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
+ glActiveTexture(GL_TEXTURE0 + mIndex);
gGL.mCurrTextureUnitIndex = mIndex;
}
}
@@ -187,7 +188,7 @@ void LLTexUnit::bindFast(LLTexture* texture)
{
LLImageGL* gl_tex = texture->getGLTexture();
- glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
+ glActiveTexture(GL_TEXTURE0 + mIndex);
gGL.mCurrTextureUnitIndex = mIndex;
mCurrTexture = gl_tex->getTexName();
if (!mCurrTexture)
@@ -334,12 +335,12 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
if (mCurrTexture != cubeMap->mImages[0]->getTexName())
{
- if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+ if (LLCubeMap::sUseCubeMaps)
{
activate();
enable(LLTexUnit::TT_CUBE_MAP);
mCurrTexture = cubeMap->mImages[0]->getTexName();
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, mCurrTexture);
mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
cubeMap->mImages[0]->updateBindStats();
if (cubeMap->mImages[0]->mTexOptionsDirty)
@@ -469,7 +470,7 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
if (mCurrTexType == TT_CUBE_MAP)
{
- glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
+ glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
}
}
@@ -515,22 +516,15 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
}
}
- if (gGLManager.mHasAnisotropic)
+ if (gGLManager.mGLVersion >= 4.59f)
{
if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
{
- if (gGL.mMaxAnisotropy < 1.f)
- {
- glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy);
-
- LL_INFOS() << "gGL.mMaxAnisotropy: " << gGL.mMaxAnisotropy << LL_ENDL ;
- gGL.mMaxAnisotropy = llmax(1.f, gGL.mMaxAnisotropy) ;
- }
- glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy);
+ glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy);
}
else
{
- glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
+ glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f);
}
}
}
@@ -544,7 +538,7 @@ GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
case TBS_PREV_ALPHA:
case TBS_ONE_MINUS_PREV_COLOR:
case TBS_ONE_MINUS_PREV_ALPHA:
- return GL_PREVIOUS_ARB;
+ return GL_PREVIOUS;
// All four cases should return the same value.
case TBS_TEX_COLOR:
@@ -558,18 +552,18 @@ GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
case TBS_VERT_ALPHA:
case TBS_ONE_MINUS_VERT_COLOR:
case TBS_ONE_MINUS_VERT_ALPHA:
- return GL_PRIMARY_COLOR_ARB;
+ return GL_PRIMARY_COLOR;
// All four cases should return the same value.
case TBS_CONST_COLOR:
case TBS_CONST_ALPHA:
case TBS_ONE_MINUS_CONST_COLOR:
case TBS_ONE_MINUS_CONST_ALPHA:
- return GL_CONSTANT_ARB;
+ return GL_CONSTANT;
default:
LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL;
- return GL_PRIMARY_COLOR_ARB;
+ return GL_PRIMARY_COLOR;
}
}
@@ -638,10 +632,10 @@ void LLTexUnit::debugTextureUnit(void)
if (mIndex < 0) return;
GLint activeTexture;
- glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
- if ((GL_TEXTURE0_ARB + mIndex) != activeTexture)
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
+ if ((GL_TEXTURE0 + mIndex) != activeTexture)
{
- U32 set_unit = (activeTexture - GL_TEXTURE0_ARB);
+ U32 set_unit = (activeTexture - GL_TEXTURE0);
LL_WARNS() << "Incorrect Texture Unit! Expected: " << set_unit << " Actual: " << mIndex << LL_ENDL;
}
}
@@ -649,29 +643,6 @@ void LLTexUnit::debugTextureUnit(void)
void LLTexUnit::setTextureColorSpace(eTextureColorSpace space)
{
mTexColorSpace = space;
-
-#if USE_SRGB_DECODE
- if (gGLManager.mHasTexturesRGBDecode)
- {
- if (space == TCS_SRGB)
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
- }
- else
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
- }
-
- if (gDebugGL)
- {
- assert_glerror();
- }
- }
- else
- {
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
- }
-#endif
}
LLLightState::LLLightState(S32 index)
@@ -734,6 +705,24 @@ void LLLightState::setSunPrimary(bool v)
}
}
+void LLLightState::setSize(F32 v)
+{
+ if (mSize != v)
+ {
+ ++gGL.mLightHash;
+ mSize = v;
+ }
+}
+
+void LLLightState::setFalloff(F32 v)
+{
+ if (mFalloff != v)
+ {
+ ++gGL.mLightHash;
+ mFalloff = v;
+ }
+}
+
void LLLightState::setAmbient(const LLColor4& ambient)
{
if (mAmbient != ambient)
@@ -827,8 +816,7 @@ LLRender::LLRender()
mCount(0),
mQuadCycle(0),
mMode(LLRender::TRIANGLES),
- mCurrTextureUnitIndex(0),
- mMaxAnisotropy(0.f)
+ mCurrTextureUnitIndex(0)
{
mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
@@ -869,14 +857,14 @@ LLRender::~LLRender()
shutdown();
}
-void LLRender::init()
+void LLRender::init(bool needs_vertex_buffer)
{
#if LL_WINDOWS
if (gGLManager.mHasDebugOutput && gDebugGL)
{ //setup debug output callback
- //glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
- glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
- glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ //glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
+ glDebugMessageCallback((GLDEBUGPROC) gl_debug_callback, NULL);
+ glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
}
#endif
@@ -888,24 +876,37 @@ void LLRender::init()
glCullFace(GL_BACK);
+ // necessary for reflection maps
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+
if (sGLCoreProfile && !LLVertexBuffer::sUseVAO)
{ //bind a dummy vertex array object so we're core profile compliant
-#ifdef GL_ARB_vertex_array_object
U32 ret;
glGenVertexArrays(1, &ret);
glBindVertexArray(ret);
-#endif
}
+ if (needs_vertex_buffer)
+ {
+ initVertexBuffer();
+ }
+}
+
+void LLRender::initVertexBuffer()
+{
+ llassert_always(mBuffer.isNull());
+ stop_glerror();
+ mBuffer = new LLVertexBuffer(immediate_mask, 0);
+ mBuffer->allocateBuffer(4096, 0, TRUE);
+ mBuffer->getVertexStrider(mVerticesp);
+ mBuffer->getTexCoord0Strider(mTexcoordsp);
+ mBuffer->getColorStrider(mColorsp);
+ stop_glerror();
+}
- llassert_always(mBuffer.isNull()) ;
- stop_glerror();
- mBuffer = new LLVertexBuffer(immediate_mask, 0);
- mBuffer->allocateBuffer(4096, 0, TRUE);
- mBuffer->getVertexStrider(mVerticesp);
- mBuffer->getTexCoord0Strider(mTexcoordsp);
- mBuffer->getColorStrider(mColorsp);
- stop_glerror();
+void LLRender::resetVertexBuffer()
+{
+ mBuffer = NULL;
}
void LLRender::shutdown()
@@ -923,7 +924,7 @@ void LLRender::shutdown()
delete mLightState[i];
}
mLightState.clear();
- mBuffer = NULL ;
+ resetVertexBuffer();
}
void LLRender::refreshState(void)
@@ -965,6 +966,7 @@ void LLRender::syncLightState()
LLVector3 diffuse[LL_NUM_LIGHT_UNITS];
LLVector3 diffuse_b[LL_NUM_LIGHT_UNITS];
bool sun_primary[LL_NUM_LIGHT_UNITS];
+ LLVector2 size[LL_NUM_LIGHT_UNITS];
for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; i++)
{
@@ -976,17 +978,19 @@ void LLRender::syncLightState()
diffuse[i].set(light->mDiffuse.mV);
diffuse_b[i].set(light->mDiffuseB.mV);
sun_primary[i] = light->mSunIsPrimary;
+ size[i].set(light->mSize, light->mFalloff);
}
shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, LL_NUM_LIGHT_UNITS, position[0].mV);
shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, LL_NUM_LIGHT_UNITS, direction[0].mV);
shader->uniform4fv(LLShaderMgr::LIGHT_ATTENUATION, LL_NUM_LIGHT_UNITS, attenuation[0].mV);
+ shader->uniform2fv(LLShaderMgr::LIGHT_DEFERRED_ATTENUATION, LL_NUM_LIGHT_UNITS, size[0].mV);
shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, LL_NUM_LIGHT_UNITS, diffuse[0].mV);
- shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV);
+ shader->uniform3fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV);
shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_primary[0] ? 1 : 0);
- shader->uniform4fv(LLShaderMgr::AMBIENT, 1, mAmbientLightColor.mV);
- shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV);
- shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, diffuse_b[0].mV);
+ shader->uniform3fv(LLShaderMgr::AMBIENT, 1, mAmbientLightColor.mV);
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV);
+ shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, diffuse_b[0].mV);
}
}
@@ -1467,12 +1471,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
llassert(color_dfactor < BF_UNDEF);
llassert(alpha_sfactor < BF_UNDEF);
llassert(alpha_dfactor < BF_UNDEF);
- if (!gGLManager.mHasBlendFuncSeparate)
- {
- LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << LL_ENDL;
- blendFunc(color_sfactor, color_dfactor);
- return;
- }
+
if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor ||
mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor)
{
@@ -1481,8 +1480,9 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
mCurrBlendColorDFactor = color_dfactor;
mCurrBlendAlphaDFactor = alpha_dfactor;
flush();
- glBlendFuncSeparateEXT(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor],
- sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
+
+ glBlendFuncSeparate(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor],
+ sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
}
}
@@ -1625,25 +1625,34 @@ void LLRender::flush()
mCount = 0;
- if (mBuffer->useVBOs() && !mBuffer->isLocked())
- { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
- mBuffer->getVertexStrider(mVerticesp, 0, count);
- mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
- mBuffer->getColorStrider(mColorsp, 0, count);
- }
-
- mBuffer->flush();
- mBuffer->setBuffer(immediate_mask);
+ if (mBuffer)
+ {
+ if (mBuffer->useVBOs() && !mBuffer->isLocked())
+ { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
+ mBuffer->getVertexStrider(mVerticesp, 0, count);
+ mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
+ mBuffer->getColorStrider(mColorsp, 0, count);
+ }
+
+ mBuffer->flush();
+ mBuffer->setBuffer(immediate_mask);
+
+ if (mMode == LLRender::QUADS && sGLCoreProfile)
+ {
+ mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
+ mQuadCycle = 1;
+ }
+ else
+ {
+ mBuffer->drawArrays(mMode, 0, count);
+ }
+ }
+ else
+ {
+ // mBuffer is present in main thread and not present in an image thread
+ LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;
+ }
- if (mMode == LLRender::QUADS && sGLCoreProfile)
- {
- mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
- mQuadCycle = 1;
- }
- else
- {
- mBuffer->drawArrays(mMode, 0, count);
- }
mVerticesp[0] = mVerticesp[count];
mTexcoordsp[0] = mTexcoordsp[count];
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index e2489876e4..6dd5f9601e 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -52,7 +52,7 @@ class LLTexture ;
#define LL_MATRIX_STACK_DEPTH 32
-class LLTexUnit
+class LLTexUnit
{
friend class LLRender;
public:
@@ -63,6 +63,7 @@ public:
TT_TEXTURE = 0, // Standard 2D Texture
TT_RECT_TEXTURE, // Non power of 2 texture
TT_CUBE_MAP, // 6-sided cube map texture
+ TT_CUBE_MAP_ARRAY, // Array of cube maps
TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample
TT_TEXTURE_3D, // standard 3D Texture
TT_NONE, // No texture type is currently enabled
@@ -245,6 +246,8 @@ public:
void setSpotCutoff(const F32& cutoff);
void setSpotDirection(const LLVector3& direction);
void setSunPrimary(bool v);
+ void setSize(F32 size);
+ void setFalloff(F32 falloff);
protected:
friend class LLRender;
@@ -265,6 +268,8 @@ protected:
F32 mSpotExponent;
F32 mSpotCutoff;
+ F32 mSize = 0.f;
+ F32 mFalloff = 0.f;
};
class LLRender
@@ -354,7 +359,9 @@ public:
LLRender();
~LLRender();
- void init() ;
+ void init(bool needs_vertex_buffer);
+ void initVertexBuffer();
+ void resetVertexBuffer();
void shutdown();
// Refreshes renderer state to the cached values
@@ -488,8 +495,6 @@ private:
eBlendFactor mCurrBlendAlphaSFactor;
eBlendFactor mCurrBlendAlphaDFactor;
- F32 mMaxAnisotropy;
-
std::vector<LLVector3> mUIOffset;
std::vector<LLVector3> mUIScale;
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index 5cb1dc6b25..3d32d3ca31 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -1516,7 +1516,15 @@ void LLRender2D::loadIdentity()
void LLRender2D::setLineWidth(F32 width)
{
gGL.flush();
- glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
+ // If outside the allowed range, glLineWidth fails with "invalid value".
+ // On Darwin, the range is [1, 1].
+ static GLfloat range[2]{0.0};
+ if (range[1] == 0)
+ {
+ glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
+ }
+ width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f);
+ glLineWidth(llclamp(width, range[0], range[1]));
}
LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 0408010513..01ccf3d314 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -119,6 +119,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize);
resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
@@ -133,7 +134,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
mUsage = usage;
mUseDepth = depth;
- if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
+ if ((sUseFBO || use_fbo))
{
if (depth)
{
@@ -149,6 +150,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
if (mDepth)
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+ llassert(!mStencil); // use of stencil buffer is deprecated (performance penalty)
if (mStencil)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
@@ -219,6 +221,7 @@ void LLRenderTarget::releaseColorAttachment()
bool LLRenderTarget::addColorAttachment(U32 color_fmt)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
if (color_fmt == 0)
{
return true;
@@ -232,11 +235,9 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
llassert( offset < 4 );
return false;
}
- if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) )
+ if( offset > 0 && (mFBO == 0) )
{
- LL_WARNS() << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << LL_ENDL;
llassert( mFBO != 0 );
- llassert( gGLManager.mHasDrawBuffers );
return false;
}
@@ -301,13 +302,11 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
mTex.push_back(tex);
mInternalFormat.push_back(color_fmt);
-#if !LL_DARWIN
if (gDebugGL)
{ //bind and unbind to validate target
bindTarget();
flush();
}
-#endif
return true;
@@ -315,6 +314,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
bool LLRenderTarget::allocateDepth()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
if (mStencil)
{
//use render buffers where stencil buffers are in play
@@ -371,6 +371,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
stop_glerror();
+ llassert(!mStencil); // deprecated -- performance penalty
if (mStencil)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
@@ -395,6 +396,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
void LLRenderTarget::release()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
if (mDepth)
{
if (mStencil)
@@ -417,6 +419,7 @@ void LLRenderTarget::release()
if (mUseDepth)
{ //detach shared depth buffer
+ llassert(!mStencil); //deprecated, performance penalty
if (mStencil)
{ //attached as a renderbuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
@@ -469,6 +472,9 @@ void LLRenderTarget::release()
void LLRenderTarget::bindTarget()
{
+ LL_PROFILE_GPU_ZONE("bindTarget");
+ llassert(mFBO);
+
if (mFBO)
{
stop_glerror();
@@ -478,19 +484,15 @@ void LLRenderTarget::bindTarget()
sCurFBO = mFBO;
stop_glerror();
- if (gGLManager.mHasDrawBuffers)
- { //setup multiple render targets
- GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
- GL_COLOR_ATTACHMENT1,
- GL_COLOR_ATTACHMENT2,
- GL_COLOR_ATTACHMENT3};
- LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x4000FF )
- glDrawBuffersARB(mTex.size(), drawbuffers);
- }
+ //setup multiple render targets
+ GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
+ GL_COLOR_ATTACHMENT1,
+ GL_COLOR_ATTACHMENT2,
+ GL_COLOR_ATTACHMENT3};
+ glDrawBuffers(mTex.size(), drawbuffers);
if (mTex.empty())
{ //no color buffer to draw to
- LL_PROFILER_GPU_ZONEC( "gl.DrawBuffer", 0x0000FF )
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
@@ -511,10 +513,13 @@ void LLRenderTarget::bindTarget()
void LLRenderTarget::clear(U32 mask_in)
{
+ LL_PROFILE_GPU_ZONE("clear");
+ llassert(mFBO);
U32 mask = GL_COLOR_BUFFER_BIT;
if (mUseDepth)
{
- mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
+ mask |= GL_DEPTH_BUFFER_BIT; // stencil buffer is deprecated, performance pnealty | GL_STENCIL_BUFFER_BIT;
+
}
if (mFBO)
{
@@ -575,7 +580,9 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt
void LLRenderTarget::flush(bool fetch_depth)
{
+ LL_PROFILE_GPU_ZONE("rt flush");
gGL.flush();
+ llassert(mFBO);
if (!mFBO)
{
gGL.getTexUnit(0)->bind(this);
@@ -620,6 +627,8 @@ void LLRenderTarget::flush(bool fetch_depth)
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
{
+ LL_PROFILE_GPU_ZONE("LLRenderTarget::copyContents");
+
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
LLGLDepthTest depth(write_depth, write_depth);
@@ -675,6 +684,7 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
}
{
+ LL_PROFILE_GPU_ZONE("copyContentsToFramebuffer");
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
LLGLDepthTest depth(write_depth, write_depth);
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index c100c182dd..7f7829c18e 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -145,6 +145,11 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
// NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->calculatesAtmospherics)
{
+ if (!shader->attachVertexObject("environment/srgbF.glsl")) // NOTE -- "F" suffix is superfluous here, there is nothing fragment specific in srgbF
+ {
+ return FALSE;
+ }
+
if (!shader->attachVertexObject("windlight/atmosphericsFuncs.glsl")) {
return FALSE;
}
@@ -177,6 +182,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
///////////////////////////////////////
// NOTE order of shader object attaching is VERY IMPORTANT!!!
+ if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics)
+ {
+ if (!shader->attachFragmentObject("environment/srgbF.glsl"))
+ {
+ return FALSE;
+ }
+ }
if(features->calculatesAtmospherics)
{
@@ -202,7 +214,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
// we want this BEFORE shadows and AO because those facilities use pos/norm access
- if (features->isDeferred)
+ if (features->isDeferred || features->hasReflectionProbes)
{
if (!shader->attachFragmentObject("deferred/deferredUtil.glsl"))
{
@@ -218,6 +230,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
+ if (features->hasReflectionProbes)
+ {
+ if (!shader->attachFragmentObject("deferred/reflectionProbeF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
if (features->hasAmbientOcclusion)
{
if (!shader->attachFragmentObject("deferred/aoUtil.glsl"))
@@ -242,14 +262,6 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
- if (features->hasSrgb)
- {
- if (!shader->attachFragmentObject("environment/srgbF.glsl"))
- {
- return FALSE;
- }
- }
-
if (features->encodesNormal)
{
if (!shader->attachFragmentObject("environment/encodeNormF.glsl"))
@@ -550,26 +562,59 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
//============================================================================
// Load Shader
-static std::string get_object_log(GLhandleARB ret)
+static std::string get_shader_log(GLuint ret)
{
std::string res;
//get log length
GLint length;
- glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
+ glGetShaderiv(ret, GL_INFO_LOG_LENGTH, &length);
if (length > 0)
{
//the log could be any size, so allocate appropriately
- GLcharARB* log = new GLcharARB[length];
- glGetInfoLogARB(ret, length, &length, log);
+ GLchar* log = new GLchar[length];
+ glGetShaderInfoLog(ret, length, &length, log);
res = std::string((char *)log);
delete[] log;
}
return res;
}
+static std::string get_program_log(GLuint ret)
+{
+ std::string res;
+
+ //get log length
+ GLint length;
+ glGetProgramiv(ret, GL_INFO_LOG_LENGTH, &length);
+ if (length > 0)
+ {
+ //the log could be any size, so allocate appropriately
+ GLchar* log = new GLchar[length];
+ glGetProgramInfoLog(ret, length, &length, log);
+ res = std::string((char*)log);
+ delete[] log;
+ }
+ return res;
+}
+
+// get the info log for the given object, be it a shader or program object
+// NOTE: ret MUST be a shader OR a program object
+static std::string get_object_log(GLuint ret)
+{
+ if (glIsProgram(ret))
+ {
+ return get_program_log(ret);
+ }
+ else
+ {
+ llassert(glIsShader(ret));
+ return get_shader_log(ret);
+ }
+}
+
//dump shader source for debugging
-void LLShaderMgr::dumpShaderSource(U32 shader_code_count, GLcharARB** shader_code_text)
+void LLShaderMgr::dumpShaderSource(U32 shader_code_count, GLchar** shader_code_text)
{
char num_str[16]; // U32 = max 10 digits
@@ -584,9 +629,10 @@ void LLShaderMgr::dumpShaderSource(U32 shader_code_count, GLcharARB** shader_cod
LL_CONT << LL_ENDL;
}
-void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& filename)
+void LLShaderMgr::dumpObjectLog(GLuint ret, BOOL warns, const std::string& filename)
{
- std::string log = get_object_log(ret);
+ std::string log;
+ log = get_object_log(ret);
std::string fname = filename;
if (filename.empty())
{
@@ -600,7 +646,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string&
}
}
-GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
+GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
{
// endsure work-around for missing GLSL funcs gets propogated to feature shader files (e.g. srgbF.glsl)
@@ -665,15 +711,15 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (file == NULL)
{
- LL_SHADER_LOADING_WARNS() << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
+ LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
return 0;
}
//we can't have any lines longer than 1024 characters
//or any shaders longer than 4096 lines... deal - DaveP
- GLcharARB buff[1024];
- GLcharARB *extra_code_text[1024];
- GLcharARB *shader_code_text[4096 + LL_ARRAY_SIZE(extra_code_text)] = { NULL };
+ GLchar buff[1024];
+ GLchar *extra_code_text[1024];
+ GLchar *shader_code_text[4096 + LL_ARRAY_SIZE(extra_code_text)] = { NULL };
GLuint extra_code_count = 0, shader_code_count = 0;
BOOST_STATIC_ASSERT(LL_ARRAY_SIZE(extra_code_text) < LL_ARRAY_SIZE(shader_code_text));
@@ -712,8 +758,15 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
{
if (major_version >= 4)
{
- //set version to 400
- shader_code_text[shader_code_count++] = strdup("#version 400\n");
+ //set version to 400 or 420
+ if (minor_version >= 20)
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 420\n");
+ }
+ else
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 400\n");
+ }
}
else if (major_version == 3)
{
@@ -748,7 +801,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
extra_code_text[extra_code_count++] = strdup("#define ATTRIBUTE in\n");
- if (type == GL_VERTEX_SHADER_ARB)
+ if (type == GL_VERTEX_SHADER)
{ //"varying" state is "out" in a vertex program, "in" in a fragment program
// ("varying" is deprecated after version 1.20)
extra_code_text[extra_code_count++] = strdup("#define VARYING out\n");
@@ -772,13 +825,20 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
extra_code_text[extra_code_count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
}
}
-
+
+ // Use alpha float to store bit flags
+ // See: C++: addDeferredAttachment(), shader: frag_data[2]
+ extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill
+ extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_ATMOS 0.34\n"); // bit 0
+ extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_PBR 0.67\n"); // bit 1
+ extra_code_text[extra_code_count++] = strdup("#define GET_GBUFFER_FLAG(flag) (abs(norm.w-flag)< 0.1)\n");
+
if (defines)
{
for (std::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
- extra_code_text[extra_code_count++] = (GLcharARB *) strdup(define.c_str());
+ extra_code_text[extra_code_count++] = (GLchar *) strdup(define.c_str());
}
}
@@ -787,7 +847,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
extra_code_text[extra_code_count++] = strdup( "#define IS_AMD_CARD 1\n" );
}
- if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
+ if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER)
{
//use specified number of texture channels for indexed texture rendering
@@ -927,7 +987,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
else
{
- shader_code_text[shader_code_count] = (GLcharARB *)strdup((char *)buff);
+ shader_code_text[shader_code_count] = (GLchar *)strdup((char *)buff);
if(flag_write_to_out_of_extra_block_area & flags)
{
@@ -964,40 +1024,40 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
fclose(file);
//create shader object
- GLhandleARB ret = glCreateShaderObjectARB(type);
+ GLuint ret = glCreateShader(type);
error = glGetError();
if (error != GL_NO_ERROR)
{
- LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << " for file: " << open_file_name << LL_ENDL;
+ LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShader: " << error << " for file: " << open_file_name << LL_ENDL;
}
//load source
- glShaderSourceARB(ret, shader_code_count, (const GLcharARB**) shader_code_text, NULL);
+ glShaderSource(ret, shader_code_count, (const GLchar**) shader_code_text, NULL);
error = glGetError();
if (error != GL_NO_ERROR)
{
- LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << " for file: " << open_file_name << LL_ENDL;
+ LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSource: " << error << " for file: " << open_file_name << LL_ENDL;
}
//compile source
- glCompileShaderARB(ret);
+ glCompileShader(ret);
error = glGetError();
if (error != GL_NO_ERROR)
{
- LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << " for file: " << open_file_name << LL_ENDL;
+ LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShader: " << error << " for file: " << open_file_name << LL_ENDL;
}
if (error == GL_NO_ERROR)
{
//check for errors
GLint success = GL_TRUE;
- glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
+ glGetShaderiv(ret, GL_COMPILE_STATUS, &success);
error = glGetError();
- if (error != GL_NO_ERROR || success == GL_FALSE)
+ if (error != GL_NO_ERROR || success == GL_FALSE)
{
//an error occured, print log
LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
@@ -1022,10 +1082,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (ret)
{
// Add shader file to map
- if (type == GL_VERTEX_SHADER_ARB) {
+ if (type == GL_VERTEX_SHADER) {
mVertexShaderObjects[filename] = ret;
}
- else if (type == GL_FRAGMENT_SHADER_ARB) {
+ else if (type == GL_FRAGMENT_SHADER) {
mFragmentShaderObjects[filename] = ret;
}
shader_level = try_gpu_class;
@@ -1042,19 +1102,21 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
return ret;
}
-BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
+BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors)
{
//check for errors
- glLinkProgramARB(obj);
+ glLinkProgram(obj);
GLint success = GL_TRUE;
- glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success);
+ glGetProgramiv(obj, GL_LINK_STATUS, &success);
if (!suppress_errors && success == GL_FALSE)
{
//an error occured, print log
LL_SHADER_LOADING_WARNS() << "GLSL Linker Error:" << LL_ENDL;
+ dumpObjectLog(obj, TRUE, "linker");
+ return success;
}
- std::string log = get_object_log(obj);
+ std::string log = get_program_log(obj);
LLStringUtil::toLower(log);
if (log.find("software") != std::string::npos)
{
@@ -1065,12 +1127,12 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
return success;
}
-BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
+BOOL LLShaderMgr::validateProgramObject(GLuint obj)
{
//check program validity against current GL
- glValidateProgramARB(obj);
+ glValidateProgram(obj);
GLint success = GL_TRUE;
- glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
+ glGetProgramiv(obj, GL_LINK_STATUS, &success);
if (success == GL_FALSE)
{
LL_SHADER_LOADING_WARNS() << "GLSL program not valid: " << LL_ENDL;
@@ -1122,6 +1184,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("light_position");
mReservedUniforms.push_back("light_direction");
mReservedUniforms.push_back("light_attenuation");
+ mReservedUniforms.push_back("light_deferred_attenuation");
mReservedUniforms.push_back("light_diffuse");
mReservedUniforms.push_back("light_ambient");
mReservedUniforms.push_back("light_count");
@@ -1148,13 +1211,19 @@ void LLShaderMgr::initAttribsAndUniforms()
llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
mReservedUniforms.push_back("color");
-
+ mReservedUniforms.push_back("emissiveColor");
+ mReservedUniforms.push_back("metallicFactor");
+ mReservedUniforms.push_back("roughnessFactor");
+
mReservedUniforms.push_back("diffuseMap");
mReservedUniforms.push_back("altDiffuseMap");
mReservedUniforms.push_back("specularMap");
+ mReservedUniforms.push_back("emissiveMap");
mReservedUniforms.push_back("bumpMap");
mReservedUniforms.push_back("bumpMap2");
mReservedUniforms.push_back("environmentMap");
+ mReservedUniforms.push_back("reflectionProbes");
+ mReservedUniforms.push_back("irradianceProbes");
mReservedUniforms.push_back("cloud_noise_texture");
mReservedUniforms.push_back("cloud_noise_texture_next");
mReservedUniforms.push_back("fullbright");
@@ -1162,9 +1231,12 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("sunlight_color");
mReservedUniforms.push_back("ambient_color");
mReservedUniforms.push_back("blue_horizon");
+ mReservedUniforms.push_back("blue_horizon_linear");
mReservedUniforms.push_back("blue_density");
+ mReservedUniforms.push_back("blue_density_linear");
mReservedUniforms.push_back("haze_horizon");
mReservedUniforms.push_back("haze_density");
+ mReservedUniforms.push_back("haze_density_linear");
mReservedUniforms.push_back("cloud_shadow");
mReservedUniforms.push_back("density_multiplier");
mReservedUniforms.push_back("distance_multiplier");
@@ -1201,6 +1273,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("minimum_alpha");
mReservedUniforms.push_back("emissive_brightness");
+ // Deferred
mReservedUniforms.push_back("shadow_matrix");
mReservedUniforms.push_back("env_mat");
mReservedUniforms.push_back("shadow_clip");
@@ -1225,8 +1298,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("depth_cutoff");
mReservedUniforms.push_back("norm_cutoff");
mReservedUniforms.push_back("shadow_target_width");
+ mReservedUniforms.push_back("view_dir"); // DEFERRED_VIEW_DIR
- llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH+1);
+ llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_VIEW_DIR+1);
mReservedUniforms.push_back("tc_scale");
mReservedUniforms.push_back("rcp_screen_res");
@@ -1256,6 +1330,8 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("positionMap");
mReservedUniforms.push_back("diffuseRect");
mReservedUniforms.push_back("specularRect");
+ mReservedUniforms.push_back("emissiveRect");
+ mReservedUniforms.push_back("brdfLut");
mReservedUniforms.push_back("noiseMap");
mReservedUniforms.push_back("lightFunc");
mReservedUniforms.push_back("lightMap");
@@ -1281,6 +1357,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("specular");
mReservedUniforms.push_back("lightExp");
mReservedUniforms.push_back("waterFogColor");
+ mReservedUniforms.push_back("waterFogColorLinear");
mReservedUniforms.push_back("waterFogDensity");
mReservedUniforms.push_back("waterFogKS");
mReservedUniforms.push_back("refScale");
@@ -1326,6 +1403,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("halo_map");
mReservedUniforms.push_back("moon_brightness");
mReservedUniforms.push_back("cloud_variance");
+ mReservedUniforms.push_back("reflection_probe_ambiance");
mReservedUniforms.push_back("sh_input_r");
mReservedUniforms.push_back("sh_input_g");
@@ -1335,6 +1413,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("water_edge");
mReservedUniforms.push_back("sun_up_factor");
mReservedUniforms.push_back("moonlight_color");
+ mReservedUniforms.push_back("moonlight_linear");
+ mReservedUniforms.push_back("sunlight_linear");
+ mReservedUniforms.push_back("ambient_linear");
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 67c0d6ab10..6d2138f405 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -55,6 +55,7 @@ public:
LIGHT_POSITION, // "light_position"
LIGHT_DIRECTION, // "light_direction"
LIGHT_ATTENUATION, // "light_attenuation"
+ LIGHT_DEFERRED_ATTENUATION, // "light_deferred_attenuation"
LIGHT_DIFFUSE, // "light_diffuse"
LIGHT_AMBIENT, // "light_ambient"
MULTI_LIGHT_COUNT, // "light_count"
@@ -74,12 +75,18 @@ public:
PROJECTOR_LOD, // "proj_lod"
PROJECTOR_AMBIENT_LOD, // "proj_ambient_lod"
DIFFUSE_COLOR, // "color"
+ EMISSIVE_COLOR, // "emissiveColor"
+ METALLIC_FACTOR, // "metallicFactor"
+ ROUGHNESS_FACTOR, // "roughnessFactor"
DIFFUSE_MAP, // "diffuseMap"
ALTERNATE_DIFFUSE_MAP, // "altDiffuseMap"
SPECULAR_MAP, // "specularMap"
+ EMISSIVE_MAP, // "emissiveMap"
BUMP_MAP, // "bumpMap"
BUMP_MAP2, // "bumpMap2"
ENVIRONMENT_MAP, // "environmentMap"
+ REFLECTION_PROBES, // "reflectionProbes"
+ IRRADIANCE_PROBES, // "irradianceProbes"
CLOUD_NOISE_MAP, // "cloud_noise_texture"
CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next"
FULLBRIGHT, // "fullbright"
@@ -87,9 +94,12 @@ public:
SUNLIGHT_COLOR, // "sunlight_color"
AMBIENT, // "ambient_color"
BLUE_HORIZON, // "blue_horizon"
+ BLUE_HORIZON_LINEAR, // "blue_horizon_linear"
BLUE_DENSITY, // "blue_density"
+ BLUE_DENSITY_LINEAR, // "blue_density_linear"
HAZE_HORIZON, // "haze_horizon"
HAZE_DENSITY, // "haze_density"
+ HAZE_DENSITY_LINEAR, // "haze_density_linear"
CLOUD_SHADOW, // "cloud_shadow"
DENSITY_MULTIPLIER, // "density_multiplier"
DISTANCE_MULTIPLIER, // "distance_multiplier"
@@ -142,6 +152,7 @@ public:
DEFERRED_DEPTH_CUTOFF, // "depth_cutoff"
DEFERRED_NORM_CUTOFF, // "norm_cutoff"
DEFERRED_SHADOW_TARGET_WIDTH, // "shadow_target_width"
+ DEFERRED_VIEW_DIR, // "view_dir"
FXAA_TC_SCALE, // "tc_scale"
FXAA_RCP_SCREEN_RES, // "rcp_screen_res"
@@ -168,6 +179,8 @@ public:
DEFERRED_POSITION, // "positionMap"
DEFERRED_DIFFUSE, // "diffuseRect"
DEFERRED_SPECULAR, // "specularRect"
+ DEFERRED_EMISSIVE, // "emissiveRect"
+ DEFERRED_BRDF_LUT, // "brdfLut"
DEFERRED_NOISE, // "noiseMap"
DEFERRED_LIGHTFUNC, // "lightFunc"
DEFERRED_LIGHT, // "lightMap"
@@ -192,6 +205,7 @@ public:
WATER_SPECULAR, // "specular"
WATER_SPECULAR_EXP, // "lightExp"
WATER_FOGCOLOR, // "waterFogColor"
+ WATER_FOGCOLOR_LINEAR, // "waterFogColorLinear"
WATER_FOGDENSITY, // "waterFogDensity"
WATER_FOGKS, // "waterFogKS"
WATER_REFSCALE, // "refScale"
@@ -242,6 +256,7 @@ public:
CLOUD_VARIANCE, // "cloud_variance"
+ REFLECTION_PROBE_AMBIANCE, // "reflection_probe_ambiance"
SH_INPUT_L1R, // "sh_input_r"
SH_INPUT_L1G, // "sh_input_g"
SH_INPUT_L1B, // "sh_input_b"
@@ -250,6 +265,9 @@ public:
WATER_EDGE_FACTOR, // "water_edge"
SUN_UP_FACTOR, // "sun_up_factor"
MOONLIGHT_COLOR, // "moonlight_color"
+ MOONLIGHT_LINEAR, // "moonlight_LINEAR"
+ SUNLIGHT_LINEAR, // "sunlight_linear"
+ AMBIENT_LINEAR, // "ambient_linear"
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
// clang-format on
@@ -260,11 +278,11 @@ public:
virtual void initAttribsAndUniforms(void);
BOOL attachShaderFeatures(LLGLSLShader * shader);
- void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE, const std::string& filename = "");
- void dumpShaderSource(U32 shader_code_count, GLcharARB** shader_code_text);
- BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
- BOOL validateProgramObject(GLhandleARB obj);
- GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
+ void dumpObjectLog(GLuint ret, BOOL warns = TRUE, const std::string& filename = "");
+ void dumpShaderSource(U32 shader_code_count, GLchar** shader_code_text);
+ BOOL linkProgramObject(GLuint obj, BOOL suppress_errors = FALSE);
+ BOOL validateProgramObject(GLuint obj);
+ GLuint loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
@@ -274,8 +292,8 @@ public:
public:
// Map of shader names to compiled
- std::map<std::string, GLhandleARB> mVertexShaderObjects;
- std::map<std::string, GLhandleARB> mFragmentShaderObjects;
+ std::map<std::string, GLuint> mVertexShaderObjects;
+ std::map<std::string, GLuint> mFragmentShaderObjects;
//global (reserved slot) shader parameters
std::vector<std::string> mReservedAttribs;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 6338cab96a..f51000b9a6 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -83,11 +83,11 @@ const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
//============================================================================
//static
-LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
-LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
-LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY_ARB, GL_ARRAY_BUFFER_ARB);
-LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
-LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW, GL_ARRAY_BUFFER);
+LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
+LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY, GL_ARRAY_BUFFER);
+LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW, GL_ELEMENT_ARRAY_BUFFER);
+LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW, GL_ELEMENT_ARRAY_BUFFER);
U32 LLVBOPool::sBytesPooled = 0;
U32 LLVBOPool::sIndexBytesPooled = 0;
@@ -127,7 +127,7 @@ U32 LLVBOPool::genBuffer()
if (sNameIdx == 0)
{
- glGenBuffersARB(1024, sNamePool);
+ glGenBuffers(1024, sNamePool);
sNameIdx = 1024;
}
@@ -141,11 +141,11 @@ void LLVBOPool::deleteBuffer(U32 name)
{
LLVertexBuffer::unbind();
- glBindBufferARB(mType, name);
- glBufferDataARB(mType, 0, NULL, mUsage);
- glBindBufferARB(mType, 0);
+ glBindBuffer(mType, name);
+ glBufferData(mType, 0, NULL, mUsage);
+ glBindBuffer(mType, 0);
- glDeleteBuffersARB(1, &name);
+ glDeleteBuffers(1, &name);
}
}
@@ -175,15 +175,15 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
//make a new buffer
name = genBuffer();
-
- glBindBufferARB(mType, name);
+
+ glBindBuffer(mType, name);
if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
{ //record this miss
mMissCount[i]++;
}
- if (mType == GL_ARRAY_BUFFER_ARB)
+ if (mType == GL_ARRAY_BUFFER)
{
LLVertexBuffer::sAllocatedBytes += size;
}
@@ -192,10 +192,10 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
LLVertexBuffer::sAllocatedIndexBytes += size;
}
- if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
+ if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW)
{
- glBufferDataARB(mType, size, 0, mUsage);
- if (mUsage != GL_DYNAMIC_COPY_ARB)
+ glBufferData(mType, size, 0, mUsage);
+ if (mUsage != GL_DYNAMIC_COPY)
{ //data will be provided by application
ret = (U8*) ll_aligned_malloc<64>(size);
if (!ret)
@@ -212,10 +212,10 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
}
else
{ //always use a true hint of static draw when allocating non-client-backed buffers
- glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
+ glBufferData(mType, size, 0, GL_STATIC_DRAW);
}
- glBindBufferARB(mType, 0);
+ glBindBuffer(mType, 0);
if (for_seed)
{ //put into pool for future use
@@ -225,7 +225,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
rec.mGLName = name;
rec.mClientData = ret;
- if (mType == GL_ARRAY_BUFFER_ARB)
+ if (mType == GL_ARRAY_BUFFER)
{
sBytesPooled += size;
}
@@ -241,7 +241,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
name = mFreeList[i].front().mGLName;
ret = mFreeList[i].front().mClientData;
- if (mType == GL_ARRAY_BUFFER_ARB)
+ if (mType == GL_ARRAY_BUFFER)
{
sBytesPooled -= size;
}
@@ -263,7 +263,7 @@ void LLVBOPool::release(U32 name, U8* buffer, U32 size)
deleteBuffer(name);
ll_aligned_free_fallback((U8*) buffer);
- if (mType == GL_ARRAY_BUFFER_ARB)
+ if (mType == GL_ARRAY_BUFFER)
{
LLVertexBuffer::sAllocatedBytes -= size;
}
@@ -322,7 +322,7 @@ void LLVBOPool::cleanup()
l.pop_front();
- if (mType == GL_ARRAY_BUFFER_ARB)
+ if (mType == GL_ARRAY_BUFFER)
{
sBytesPooled -= size;
LLVertexBuffer::sAllocatedBytes -= size;
@@ -451,14 +451,14 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //was enabled
if (!(data_mask & mask))
{ //needs to be disabled
- glDisableVertexAttribArrayARB(loc);
+ glDisableVertexAttribArray(loc);
}
}
else
{ //was disabled
if (data_mask & mask)
{ //needs to be enabled
- glEnableVertexAttribArrayARB(loc);
+ glEnableVertexAttribArray(loc);
}
}
}
@@ -574,6 +574,12 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
}
}
+#ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+void LLVertexBuffer::setLabel(const char* label) {
+ LL_LABEL_OBJECT_GL(GL_BUFFER, mGLBuffer, strlen(label), label);
+}
+#endif
+
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
{
validateRange(start, end, count, indices_offset);
@@ -624,7 +630,6 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
stop_glerror();
LLGLSLShader::startProfile();
- LL_PROFILER_GPU_ZONEC( "gl.DrawRangeElements", 0xFFFF00 )
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
LLGLSLShader::stopProfile(count, mode);
@@ -642,7 +647,6 @@ void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32
U16* idx = ((U16*)getIndicesPointer()) + indices_offset;
- LL_PROFILER_GPU_ZONEC("gl.DrawRangeElements", 0xFFFF00)
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
}
@@ -688,8 +692,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
stop_glerror();
LLGLSLShader::startProfile();
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0xA0FFA0 )
- glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
+ glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
((U16*) getIndicesPointer()) + indices_offset);
LLGLSLShader::stopProfile(count, mode);
stop_glerror();
@@ -736,7 +739,6 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
LLGLSLShader::startProfile();
{
- LL_PROFILER_GPU_ZONEC("gl.DrawArrays", 0xFF4040)
glDrawArrays(sGLMode[mode], first, count);
}
LLGLSLShader::stopProfile(count, mode);
@@ -748,7 +750,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
//static
void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
{
- sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject;
+ sEnableVBOs = use_vbo;
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping;
}
@@ -757,9 +759,7 @@ void LLVertexBuffer::unbind()
{
if (sGLRenderArray)
{
-#if GL_ARB_vertex_array_object
glBindVertexArray(0);
-#endif
sGLRenderArray = 0;
sGLRenderIndices = 0;
sIBOActive = false;
@@ -767,12 +767,12 @@ void LLVertexBuffer::unbind()
if (sVBOActive)
{
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
sVBOActive = false;
}
if (sIBOActive)
{
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
sIBOActive = false;
}
@@ -805,32 +805,32 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
ret_usage = 0;
}
- if (ret_usage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
+ if (ret_usage == GL_STREAM_DRAW && !sUseStreamDraw)
{
ret_usage = 0;
}
- if (ret_usage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
+ if (ret_usage == GL_DYNAMIC_DRAW && sPreferStreamDraw)
{
- ret_usage = GL_STREAM_DRAW_ARB;
+ ret_usage = GL_STREAM_DRAW;
}
if (ret_usage == 0 && LLRender::sGLCoreProfile)
{ //MUST use VBOs for all rendering
- ret_usage = GL_STREAM_DRAW_ARB;
+ ret_usage = GL_STREAM_DRAW;
}
- if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)
+ if (ret_usage && ret_usage != GL_STREAM_DRAW)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
- if (ret_usage != GL_DYNAMIC_COPY_ARB)
+ if (ret_usage != GL_DYNAMIC_COPY)
{
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
- ret_usage = GL_STREAM_DRAW_ARB;
+ ret_usage = GL_STREAM_DRAW;
}
else
{
- ret_usage = GL_DYNAMIC_DRAW_ARB;
+ ret_usage = GL_DYNAMIC_DRAW;
}
}
}
@@ -863,7 +863,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage)
mMappable(false),
mFence(NULL)
{
- mMappable = (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping);
+ mMappable = (mUsage == GL_DYNAMIC_DRAW && !sDisableVBOMapping);
//zero out offsets
for (U32 i = 0; i < TYPE_MAX; i++)
@@ -927,9 +927,7 @@ LLVertexBuffer::~LLVertexBuffer()
if (mGLArray)
{
-#if GL_ARB_vertex_array_object
releaseVAOName(mGLArray);
-#endif
}
sCount--;
@@ -960,10 +958,7 @@ void LLVertexBuffer::placeFence() const
{
/*if (!mFence && useVBOs())
{
- if (gGLManager.mHasSync)
- {
- mFence = new LLGLSyncFence();
- }
+ mFence = new LLGLSyncFence();
}
if (mFence)
@@ -986,11 +981,11 @@ void LLVertexBuffer::genBuffer(U32 size)
{
mSize = vbo_block_size(size);
- if (mUsage == GL_STREAM_DRAW_ARB)
+ if (mUsage == GL_STREAM_DRAW)
{
mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);
}
- else if (mUsage == GL_DYNAMIC_DRAW_ARB)
+ else if (mUsage == GL_DYNAMIC_DRAW)
{
mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
}
@@ -1007,7 +1002,7 @@ void LLVertexBuffer::genIndices(U32 size)
{
mIndicesSize = vbo_block_size(size);
- if (mUsage == GL_STREAM_DRAW_ARB)
+ if (mUsage == GL_STREAM_DRAW)
{
mMappedIndexData = sStreamIBOPool.allocate(mGLIndices, mIndicesSize);
}
@@ -1021,7 +1016,7 @@ void LLVertexBuffer::genIndices(U32 size)
void LLVertexBuffer::releaseBuffer()
{
- if (mUsage == GL_STREAM_DRAW_ARB)
+ if (mUsage == GL_STREAM_DRAW)
{
sStreamVBOPool.release(mGLBuffer, mMappedData, mSize);
}
@@ -1038,7 +1033,7 @@ void LLVertexBuffer::releaseBuffer()
void LLVertexBuffer::releaseIndices()
{
- if (mUsage == GL_STREAM_DRAW_ARB)
+ if (mUsage == GL_STREAM_DRAW)
{
sStreamIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);
}
@@ -1055,7 +1050,7 @@ void LLVertexBuffer::releaseIndices()
bool LLVertexBuffer::createGLBuffer(U32 size)
{
- if (mGLBuffer)
+ if (mGLBuffer || mMappedData)
{
destroyGLBuffer();
}
@@ -1079,6 +1074,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
{
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
+
mMappedData = (U8*)ll_aligned_malloc_16(size);
mSize = size;
}
@@ -1238,11 +1234,9 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
//actually allocate space for the vertex buffer if using VBO mapping
flush(); //unmap
- if (gGLManager.mHasVertexArrayObject && useVBOs() && sUseVAO)
+ if (useVBOs() && sUseVAO)
{
-#if GL_ARB_vertex_array_object
mGLArray = getVAOName();
-#endif
setupVertexArray();
}
}
@@ -1258,9 +1252,7 @@ void LLVertexBuffer::setupVertexArray()
}
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
-#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
-#endif
sGLRenderArray = mGLArray;
static const U32 attrib_size[] =
@@ -1338,11 +1330,10 @@ void LLVertexBuffer::setupVertexArray()
{
if (mTypeMask & (1 << i))
{
- glEnableVertexAttribArrayARB(i);
+ glEnableVertexAttribArray(i);
if (attrib_integer[i])
{
-#if !LL_DARWIN
//glVertexattribIPointer requires GLSL 1.30 or later
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
{
@@ -1351,9 +1342,8 @@ void LLVertexBuffer::setupVertexArray()
// Cast via intptr_t to make it painfully obvious to the
// compiler that we're doing this intentionally.
glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i],
- reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i])));
+ reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i])));
}
-#endif
}
else
{
@@ -1364,14 +1354,14 @@ void LLVertexBuffer::setupVertexArray()
// pointer value. Ruslan asserts that in this case the last
// param is interpreted as an array data offset within the VBO
// rather than as an actual pointer, so it's okay.
- glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i],
+ glVertexAttribPointer(i, attrib_size[i], attrib_type[i],
attrib_normalized[i], sTypeSize[i],
reinterpret_cast<GLvoid*>(intptr_t(mOffsets[i])));
}
}
else
{
- glDisableVertexAttribArrayARB(i);
+ glDisableVertexAttribArray(i);
}
}
@@ -1447,7 +1437,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
if (useVBOs())
{
- if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappable)
{
if (count == -1)
{
@@ -1496,62 +1486,34 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
{
U8* src = NULL;
waitFence();
- if (gGLManager.mHasMapBufferRange)
+ if (map_range)
{
- if (map_range)
- {
-#ifdef GL_ARB_map_buffer_range
- S32 offset = mOffsets[type] + sTypeSize[type]*index;
- S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
- src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length,
- GL_MAP_WRITE_BIT |
- GL_MAP_FLUSH_EXPLICIT_BIT |
- GL_MAP_INVALIDATE_RANGE_BIT);
-#endif
- }
- else
+ S32 offset = mOffsets[type] + sTypeSize[type]*index;
+ S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
+ src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT);
+ }
+ else
+ {
+ if (gDebugGL)
{
-#ifdef GL_ARB_map_buffer_range
+ GLint size = 0;
+ glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
- if (gDebugGL)
+ if (size < mSize)
{
- GLint size = 0;
- glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
-
- if (size < mSize)
- {
- LL_ERRS() << "Invalid buffer size." << LL_ENDL;
- }
+ LL_ERRS() << "Invalid buffer size." << LL_ENDL;
}
-
- src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,
- GL_MAP_WRITE_BIT |
- GL_MAP_FLUSH_EXPLICIT_BIT);
-#endif
- }
- }
- else if (gGLManager.mHasFlushBufferRange)
- {
- if (map_range)
- {
-#ifndef LL_MESA_HEADLESS
- glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
- glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
-#endif
- src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- }
- else
- {
- src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
- }
- else
- {
- map_range = false;
- src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+ src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT);
}
- llassert(src != NULL);
+ llassert(src != NULL);
mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
mAlignedOffset = mMappedData - src;
@@ -1572,12 +1534,12 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
//print out more debug info before crash
LL_INFOS() << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << LL_ENDL;
GLint size;
- glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
- LL_INFOS() << "GL_ARRAY_BUFFER_ARB size is " << size << LL_ENDL;
+ glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
+ LL_INFOS() << "GL_ARRAY_BUFFER size is " << size << LL_ENDL;
//--------------------
GLint buff;
- glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff);
if ((GLuint)buff != mGLBuffer)
{
LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL;
@@ -1598,7 +1560,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
map_range = false;
}
- if (map_range && gGLManager.mHasMapBufferRange && mMappable)
+ if (map_range && mMappable)
{
return mMappedData;
}
@@ -1624,7 +1586,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (useVBOs())
{
- if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappable)
{
if (count == -1)
{
@@ -1665,7 +1627,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (gDebugGL && useVBOs())
{
GLint elem = 0;
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem);
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elem);
if (elem != mGLIndices)
{
@@ -1681,52 +1643,24 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
U8* src = NULL;
waitFence();
- if (gGLManager.mHasMapBufferRange)
+ if (map_range)
{
- if (map_range)
- {
-#ifdef GL_ARB_map_buffer_range
- S32 offset = sizeof(U16)*index;
- S32 length = sizeof(U16)*count;
- src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length,
- GL_MAP_WRITE_BIT |
- GL_MAP_FLUSH_EXPLICIT_BIT |
- GL_MAP_INVALIDATE_RANGE_BIT);
-#endif
- }
- else
- {
-#ifdef GL_ARB_map_buffer_range
- src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices,
- GL_MAP_WRITE_BIT |
- GL_MAP_FLUSH_EXPLICIT_BIT);
-#endif
- }
- }
- else if (gGLManager.mHasFlushBufferRange)
- {
- if (map_range)
- {
-#ifndef LL_MESA_HEADLESS
- glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
- glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
-#endif
- src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- }
- else
- {
- src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- }
+ S32 offset = sizeof(U16)*index;
+ S32 length = sizeof(U16)*count;
+ src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT);
}
else
{
- map_range = false;
- src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT);
}
-
+
llassert(src != NULL);
-
mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src);
mAlignedIndexOffset = mMappedIndexData - src;
stop_glerror();
@@ -1741,7 +1675,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if(mMappable)
{
GLint buff;
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff);
if ((GLuint)buff != mGLIndices)
{
LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL;
@@ -1760,7 +1694,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
map_range = false;
}
- if (map_range && gGLManager.mHasMapBufferRange && mMappable)
+ if (map_range && mMappable)
{
return mMappedIndexData;
}
@@ -1797,12 +1731,12 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sTypeSize[region.mType]*region.mCount;
if (mSize >= length + offset)
{
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*)mMappedData + offset);
+ glBufferSubData(GL_ARRAY_BUFFER, offset, length, (U8*)mMappedData + offset);
}
else
{
GLint size = 0;
- glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+ glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
LL_WARNS() << "Attempted to map regions to a buffer that is too small, "
<< "mapped size: " << mSize
<< ", gl buffer size: " << size
@@ -1818,41 +1752,28 @@ void LLVertexBuffer::unmapBuffer()
else
{
stop_glerror();
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (U8*) mMappedData);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, getSize(), (U8*) mMappedData);
stop_glerror();
}
}
else
{
- if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappedVertexRegions.empty())
{
- if (!mMappedVertexRegions.empty())
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex");
+ for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex");
- for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
- {
- const MappedRegion& region = mMappedVertexRegions[i];
- S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
- S32 length = sTypeSize[region.mType]*region.mCount;
- if (gGLManager.mHasMapBufferRange)
- {
-#ifdef GL_ARB_map_buffer_range
- glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
-#endif
- }
- else if (gGLManager.mHasFlushBufferRange)
- {
-#ifndef LL_MESA_HEADLESS
- glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
-#endif
- }
- }
-
- mMappedVertexRegions.clear();
+ const MappedRegion& region = mMappedVertexRegions[i];
+ S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
+ S32 length = sTypeSize[region.mType]*region.mCount;
+ glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length);
}
+
+ mMappedVertexRegions.clear();
}
+
stop_glerror();
- glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+ glUnmapBuffer(GL_ARRAY_BUFFER);
stop_glerror();
mMappedData = NULL;
@@ -1877,12 +1798,12 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sizeof(U16)*region.mCount;
if (mIndicesSize >= length + offset)
{
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, (U8*) mMappedIndexData+offset);
}
else
{
GLint size = 0;
- glGetBufferParameterivARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+ glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
LL_WARNS() << "Attempted to map regions to a buffer that is too small, "
<< "mapped size: " << mIndicesSize
<< ", gl buffer size: " << size
@@ -1898,44 +1819,28 @@ void LLVertexBuffer::unmapBuffer()
else
{
stop_glerror();
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (U8*) mMappedIndexData);
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, getIndicesSize(), (U8*) mMappedIndexData);
stop_glerror();
}
}
else
{
- if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappedIndexRegions.empty())
{
- if (!mMappedIndexRegions.empty())
+ for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
- for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index");
- const MappedRegion& region = mMappedIndexRegions[i];
- S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
- S32 length = sizeof(U16)*region.mCount;
- if (gGLManager.mHasMapBufferRange)
- {
-#ifdef GL_ARB_map_buffer_range
- glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
-#endif
- }
- else if (gGLManager.mHasFlushBufferRange)
- {
-#ifdef GL_APPLE_flush_buffer_range
-#ifndef LL_MESA_HEADLESS
- glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
-#endif
-#endif
- }
- stop_glerror();
- }
-
- mMappedIndexRegions.clear();
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index");
+ const MappedRegion& region = mMappedIndexRegions[i];
+ S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
+ S32 length = sizeof(U16)*region.mCount;
+ glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length);
+ stop_glerror();
}
+
+ mMappedIndexRegions.clear();
}
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
mMappedIndexData = NULL;
}
@@ -2064,9 +1969,7 @@ bool LLVertexBuffer::bindGLArray()
{
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
-#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
-#endif
sGLRenderArray = mGLArray;
}
@@ -2089,7 +1992,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
sVBOActive = true;
@@ -2106,7 +2009,7 @@ bool LLVertexBuffer::bindGLBufferFast()
{
if (mGLBuffer != sGLRenderBuffer || !sVBOActive)
{
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
sVBOActive = true;
@@ -2129,7 +2032,7 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
{
LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL;
}*/
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
sGLRenderIndices = mGLIndices;
stop_glerror();
sBindCount++;
@@ -2144,7 +2047,7 @@ bool LLVertexBuffer::bindGLIndicesFast()
{
if (mGLIndices != sGLRenderIndices || !sIBOActive)
{
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
sGLRenderIndices = mGLIndices;
sBindCount++;
sIBOActive = true;
@@ -2258,7 +2161,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if (gDebugGL && !mGLArray)
{
GLint buff;
- glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff);
if ((GLuint)buff != mGLBuffer)
{
if (gDebugSession)
@@ -2273,7 +2176,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if (mGLIndices)
{
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff);
if ((GLuint)buff != mGLIndices)
{
if (gDebugSession)
@@ -2294,9 +2197,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (sGLRenderArray)
{
-#if GL_ARB_vertex_array_object
glBindVertexArray(0);
-#endif
sGLRenderArray = 0;
sGLRenderIndices = 0;
sIBOActive = false;
@@ -2306,7 +2207,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (sVBOActive)
{
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
sBindCount++;
sVBOActive = false;
setup = true; // ... or a VBO is deactivated
@@ -2321,7 +2222,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (sIBOActive)
{
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
sBindCount++;
sIBOActive = false;
}
@@ -2396,89 +2297,87 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
S32 loc = TYPE_NORMAL;
void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
+ glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
}
if (data_mask & MAP_TEXCOORD3)
{
S32 loc = TYPE_TEXCOORD3;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
- glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
+ glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
}
if (data_mask & MAP_TEXCOORD2)
{
S32 loc = TYPE_TEXCOORD2;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
- glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
+ glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
}
if (data_mask & MAP_TEXCOORD1)
{
S32 loc = TYPE_TEXCOORD1;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
- glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
+ glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
}
if (data_mask & MAP_TANGENT)
{
S32 loc = TYPE_TANGENT;
void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
- glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
+ glVertexAttribPointer(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
}
if (data_mask & MAP_TEXCOORD0)
{
S32 loc = TYPE_TEXCOORD0;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
- glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
+ glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
}
if (data_mask & MAP_COLOR)
{
S32 loc = TYPE_COLOR;
//bind emissive instead of color pointer if emissive is present
void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
- glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
+ glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
}
if (data_mask & MAP_EMISSIVE)
{
S32 loc = TYPE_EMISSIVE;
void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
- glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
if (!(data_mask & MAP_COLOR))
{ //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
loc = TYPE_COLOR;
- glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
}
}
if (data_mask & MAP_WEIGHT)
{
S32 loc = TYPE_WEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
- glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+ glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
}
if (data_mask & MAP_WEIGHT4)
{
S32 loc = TYPE_WEIGHT4;
void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+ glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
}
if (data_mask & MAP_CLOTHWEIGHT)
{
S32 loc = TYPE_CLOTHWEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+ glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
}
if (data_mask & MAP_TEXTURE_INDEX &&
(gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
{
-#if !LL_DARWIN
S32 loc = TYPE_TEXTURE_INDEX;
void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
-#endif
}
if (data_mask & MAP_VERTEX)
{
S32 loc = TYPE_VERTEX;
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
- glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ glVertexAttribPointer(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
}
llglassertok();
@@ -2492,88 +2391,86 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
{
S32 loc = TYPE_NORMAL;
void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
+ glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
}
if (data_mask & MAP_TEXCOORD3)
{
S32 loc = TYPE_TEXCOORD3;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
- glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
}
if (data_mask & MAP_TEXCOORD2)
{
S32 loc = TYPE_TEXCOORD2;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
- glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
}
if (data_mask & MAP_TEXCOORD1)
{
S32 loc = TYPE_TEXCOORD1;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
- glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
}
if (data_mask & MAP_TANGENT)
{
S32 loc = TYPE_TANGENT;
void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
+ glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
}
if (data_mask & MAP_TEXCOORD0)
{
S32 loc = TYPE_TEXCOORD0;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
- glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
}
if (data_mask & MAP_COLOR)
{
S32 loc = TYPE_COLOR;
//bind emissive instead of color pointer if emissive is present
void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
- glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
+ glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
}
if (data_mask & MAP_EMISSIVE)
{
S32 loc = TYPE_EMISSIVE;
void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
- glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
if (!(data_mask & MAP_COLOR))
{ //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
loc = TYPE_COLOR;
- glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
}
}
if (data_mask & MAP_WEIGHT)
{
S32 loc = TYPE_WEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
- glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+ glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
}
if (data_mask & MAP_WEIGHT4)
{
S32 loc = TYPE_WEIGHT4;
void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+ glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
}
if (data_mask & MAP_CLOTHWEIGHT)
{
S32 loc = TYPE_CLOTHWEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+ glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
}
if (data_mask & MAP_TEXTURE_INDEX)
{
-#if !LL_DARWIN
S32 loc = TYPE_TEXTURE_INDEX;
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12);
glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
-#endif
}
if (data_mask & MAP_VERTEX)
{
S32 loc = TYPE_VERTEX;
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
}
}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index baf8407fc6..233d7785f8 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -265,7 +265,6 @@ public:
bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
- bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
@@ -288,7 +287,7 @@ public:
U8* getMappedIndices() const { return mMappedIndexData; }
S32 getOffset(S32 type) const { return mOffsets[type]; }
S32 getUsage() const { return mUsage; }
- bool isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? true : false; }
+ bool isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW) ? true : false; }
void draw(U32 mode, U32 count, U32 indices_offset) const;
void drawArrays(U32 mode, U32 offset, U32 count) const;
@@ -300,6 +299,9 @@ public:
//for debugging, validate data in given range is valid
void validateRange(U32 start, U32 end, U32 count, U32 offset) const;
+ #ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+ void setLabel(const char* label);
+ #endif
protected:
@@ -370,5 +372,11 @@ public:
static U32 sSetCount;
};
+#ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+#define LL_LABEL_VERTEX_BUFFER(buf, name) buf->setLabel(name)
+#else
+#define LL_LABEL_VERTEX_BUFFER(buf, name)
+#endif
+
#endif // LL_LLVERTEXBUFFER_H
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 0e59fdf519..8028f397f3 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -102,6 +102,7 @@ LLButton::Params::Params()
scale_image("scale_image", true),
hover_glow_amount("hover_glow_amount"),
commit_on_return("commit_on_return", true),
+ commit_on_capture_lost("commit_on_capture_lost", false),
display_pressed_state("display_pressed_state", true),
use_draw_context_alpha("use_draw_context_alpha", true),
badge("badge"),
@@ -165,6 +166,7 @@ LLButton::LLButton(const LLButton::Params& p)
mBottomVPad(p.pad_bottom),
mHoverGlowStrength(p.hover_glow_amount),
mCommitOnReturn(p.commit_on_return),
+ mCommitOnCaptureLost(p.commit_on_capture_lost),
mFadeWhenDisabled(FALSE),
mForcePressedState(false),
mDisplayPressedState(p.display_pressed_state),
@@ -475,6 +477,10 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
// We only handle the click if the click both started and ended within us
if( hasMouseCapture() )
{
+ // reset timers before focus change, to not cause
+ // additional commits if mCommitOnCaptureLost.
+ resetMouseDownTimer();
+
// Always release the mouse
gFocusMgr.setMouseCapture( NULL );
@@ -489,8 +495,6 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
// Regardless of where mouseup occurs, handle callback
if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
- resetMouseDownTimer();
-
// DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked.
// If mouseup in the widget, it's been clicked
if (pointInView(x, y))
@@ -1195,6 +1199,18 @@ void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignmen
void LLButton::onMouseCaptureLost()
{
+ if (mCommitOnCaptureLost
+ && mMouseDownTimer.getStarted())
+ {
+ if (mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
+
+ if (mIsToggle)
+ {
+ toggleState();
+ }
+
+ LLUICtrl::onCommit();
+ }
resetMouseDownTimer();
}
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 572d36996c..ccd31e90c0 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -124,6 +124,7 @@ public:
Optional<bool> is_toggle,
scale_image,
commit_on_return,
+ commit_on_capture_lost,
display_pressed_state;
Optional<F32> hover_glow_amount;
@@ -374,6 +375,7 @@ protected:
F32 mCurGlowStrength;
bool mCommitOnReturn;
+ bool mCommitOnCaptureLost;
bool mFadeWhenDisabled;
bool mForcePressedState;
bool mDisplayPressedState;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 03efd09689..d413fab270 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -259,6 +259,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
mLegacyHeaderHeight(p.legacy_header_height),
+ mDefaultRectForGroup(true),
mMinimized(FALSE),
mForeground(FALSE),
mFirstLook(TRUE),
@@ -761,17 +762,13 @@ void LLFloater::closeFloater(bool app_quitting)
for(handle_set_iter_t dependent_it = mDependents.begin();
dependent_it != mDependents.end(); )
{
-
LLFloater* floaterp = dependent_it->get();
- if (floaterp)
- {
- ++dependent_it;
- floaterp->closeFloater(app_quitting);
- }
- else
- {
- mDependents.erase(dependent_it++);
- }
+ dependent_it = mDependents.erase(dependent_it);
+ if (floaterp)
+ {
+ floaterp->mDependeeHandle = LLHandle<LLFloater>();
+ floaterp->closeFloater(app_quitting);
+ }
}
cleanupHandles();
@@ -906,7 +903,10 @@ bool LLFloater::applyRectControl()
if (last_in_group && last_in_group != this)
{
// other floaters in our group, position ourselves relative to them and don't save the rect
- mRectControl.clear();
+ if (mDefaultRectForGroup)
+ {
+ mRectControl.clear();
+ }
mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
}
else
@@ -1439,7 +1439,7 @@ void LLFloater::cleanupHandles()
LLFloater* floaterp = dependent_it->get();
if (!floaterp)
{
- mDependents.erase(dependent_it++);
+ dependent_it = mDependents.erase(dependent_it);
}
else
{
@@ -3481,8 +3481,15 @@ void LLFloater::stackWith(LLFloater& other)
}
next_rect.translate(floater_offset, -floater_offset);
- next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
-
+ const LLRect& rect = getControlGroup()->getRect(mRectControl);
+ if (rect.notEmpty() && !mDefaultRectForGroup && mResizable)
+ {
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+ }
+ else
+ {
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
+ }
setShape(next_rect);
if (!other.getHost())
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 306760b7fb..668cd208a9 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -454,6 +454,7 @@ public:
protected:
bool mSaveRect;
+ bool mDefaultRectForGroup;
std::string mRectControl;
std::string mPosXControl;
std::string mPosYControl;
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 82b01e705d..e01aba402e 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -35,6 +35,7 @@
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluiimage.h"
+#include "llwindow.h"
static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
@@ -42,6 +43,7 @@ LLIconCtrl::Params::Params()
: image("image_name"),
color("color"),
use_draw_context_alpha("use_draw_context_alpha", true),
+ interactable("interactable", false),
scale_image("scale_image"),
min_width("min_width", 0),
min_height("min_height", 0)
@@ -52,6 +54,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
mColor(p.color()),
mImagep(p.image),
mUseDrawContextAlpha(p.use_draw_context_alpha),
+ mInteractable(p.interactable),
mPriority(0),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
@@ -81,6 +84,16 @@ void LLIconCtrl::draw()
LLUICtrl::draw();
}
+BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (mInteractable && getEnabled())
+ {
+ getWindow()->setCursor(UI_CURSOR_HAND);
+ return TRUE;
+ }
+ return LLUICtrl::handleHover(x, y, mask);
+}
+
// virtual
// value might be a string or a UUID
void LLIconCtrl::setValue(const LLSD& value)
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index dd83e78fd3..9c3b517bca 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -48,7 +48,8 @@ public:
{
Optional<LLUIImage*> image;
Optional<LLUIColor> color;
- Optional<bool> use_draw_context_alpha;
+ Optional<bool> use_draw_context_alpha,
+ interactable;
Optional<S32> min_width,
min_height;
Ignored scale_image;
@@ -67,6 +68,9 @@ public:
// llview overrides
virtual void draw();
+ // llview overrides
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+
// lluictrl overrides
virtual void setValue(const LLSD& value );
@@ -88,6 +92,7 @@ protected:
// If set to true (default), use the draw context transparency.
// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.
bool mUseDrawContextAlpha;
+ bool mInteractable;
private:
LLUIColor mColor;
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index aac28e04b9..77938edf27 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -395,7 +395,6 @@ void LLLayoutStack::updateLayout()
space_to_distribute += panelp ? ll_round((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0;
S32 remaining_space = space_to_distribute;
- F32 fraction_distributed = 0.f;
if (space_to_distribute > 0 && total_visible_fraction > 0.f)
{ // give space proportionally to visible auto resize panels
BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
@@ -404,7 +403,6 @@ void LLLayoutStack::updateLayout()
{
F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction);
S32 delta = ll_round((F32)space_to_distribute * fraction_to_distribute);
- fraction_distributed += fraction_to_distribute;
panelp->mTargetDim += delta;
remaining_space -= delta;
}
diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 303afcda15..583704418b 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -40,6 +40,7 @@ void LLMenuButton::MenuPositions::declareValues()
declare("topleft", MP_TOP_LEFT);
declare("topright", MP_TOP_RIGHT);
declare("bottomleft", MP_BOTTOM_LEFT);
+ declare("bottomright", MP_BOTTOM_RIGHT);
}
LLMenuButton::Params::Params()
@@ -212,6 +213,13 @@ void LLMenuButton::updateMenuOrigin()
mY = rect.mBottom;
break;
}
+ case MP_BOTTOM_RIGHT:
+ {
+ const LLRect& menu_rect = menu->getRect();
+ mX = rect.mRight - menu_rect.getWidth();
+ mY = rect.mBottom;
+ break;
+ }
}
}
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index 67ec1983b3..e42f8f53bd 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -41,7 +41,8 @@ public:
{
MP_TOP_LEFT,
MP_TOP_RIGHT,
- MP_BOTTOM_LEFT
+ MP_BOTTOM_LEFT,
+ MP_BOTTOM_RIGHT
} EMenuPosition;
struct MenuPositions
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 76fd789bec..4264028338 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1363,6 +1363,9 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
+
+ virtual void onFocusLost();
+ virtual void setFocus(BOOL b);
};
LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const Params& p) :
@@ -1517,6 +1520,21 @@ BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask)
return handled;
}
+void LLMenuItemBranchDownGL::onFocusLost()
+{
+ // needed for tab-based selection
+ LLMenuItemBranchGL::onFocusLost();
+ LLMenuGL::setKeyboardMode(FALSE);
+ setHighlight(FALSE);
+}
+
+void LLMenuItemBranchDownGL::setFocus(BOOL b)
+{
+ // needed for tab-based selection
+ LLMenuItemBranchGL::setFocus(b);
+ LLMenuGL::setKeyboardMode(b);
+ setHighlight(b);
+}
BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask)
{
@@ -3942,8 +3960,8 @@ void LLTearOffMenu::draw()
{
// animate towards target height
reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
- mMenu->needsArrange();
}
+ mMenu->needsArrange();
LLFloater::draw();
}
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 5cfa8ea973..3e5978eb59 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -100,7 +100,10 @@ void LLModalDialog::onOpen(const LLSD& key)
if (!sModalStack.empty())
{
LLModalDialog* front = sModalStack.front();
- front->setVisible(FALSE);
+ if (front != this)
+ {
+ front->setVisible(FALSE);
+ }
}
// This is a modal dialog. It sucks up all mouse and keyboard operations.
@@ -108,7 +111,14 @@ void LLModalDialog::onOpen(const LLSD& key)
LLUI::getInstance()->addPopup(this);
setFocus(TRUE);
- sModalStack.push_front( this );
+ std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
+ if (iter != sModalStack.end())
+ {
+ // if already present, we want to move it to front.
+ sModalStack.erase(iter);
+ }
+
+ sModalStack.push_front(this);
}
}
diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
index 209796565c..cf57b1fe76 100644
--- a/indra/llui/llprogressbar.cpp
+++ b/indra/llui/llprogressbar.cpp
@@ -69,16 +69,22 @@ void LLProgressBar::draw()
static LLTimer timer;
F32 alpha = getDrawContext().mAlpha;
- LLColor4 image_bar_color = mColorBackground.get();
- image_bar_color.setAlpha(alpha);
- mImageBar->draw(getLocalRect(), image_bar_color);
+ if (mImageBar) // optional according to parameters
+ {
+ LLColor4 image_bar_color = mColorBackground.get();
+ image_bar_color.setAlpha(alpha);
+ mImageBar->draw(getLocalRect(), image_bar_color);
+ }
- alpha *= 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
- LLColor4 bar_color = mColorBar.get();
- bar_color.mV[VALPHA] *= alpha; // modulate alpha
- LLRect progress_rect = getLocalRect();
- progress_rect.mRight = ll_round(getRect().getWidth() * (mPercentDone / 100.f));
- mImageFill->draw(progress_rect, bar_color);
+ if (mImageFill)
+ {
+ alpha *= 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
+ LLColor4 bar_color = mColorBar.get();
+ bar_color.mV[VALPHA] *= alpha; // modulate alpha
+ LLRect progress_rect = getLocalRect();
+ progress_rect.mRight = ll_round(getRect().getWidth() * (mPercentDone / 100.f));
+ mImageFill->draw(progress_rect, bar_color);
+ }
}
void LLProgressBar::setValue(const LLSD& value)
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 11b0eb9f80..65c7b420ce 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1388,6 +1388,84 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
return found;
}
+U32 LLScrollListCtrl::searchItems(const std::string& substring, bool case_sensitive, bool focus)
+{
+ return searchItems(utf8str_to_wstring(substring), case_sensitive, focus);
+}
+
+U32 LLScrollListCtrl::searchItems(const LLWString& substring, bool case_sensitive, bool focus)
+{
+ U32 found = 0;
+
+ LLWString substring_trimmed(substring);
+ S32 len = substring_trimmed.size();
+
+ if (0 == len)
+ {
+ // at the moment search for empty element is not supported
+ return 0;
+ }
+ else
+ {
+ deselectAllItems(TRUE);
+ if (!case_sensitive)
+ {
+ // do comparisons in lower case
+ LLWStringUtil::toLower(substring_trimmed);
+ }
+
+ for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ {
+ LLScrollListItem* item = *iter;
+ // Only select enabled items with matching names
+ if (!item->getEnabled())
+ {
+ continue;
+ }
+ LLScrollListCell* cellp = item->getColumn(getSearchColumn());
+ if (!cellp)
+ {
+ continue;
+ }
+ LLWString item_label = utf8str_to_wstring(cellp->getValue().asString());
+ if (!case_sensitive)
+ {
+ LLWStringUtil::toLower(item_label);
+ }
+ // remove extraneous whitespace from searchable label
+ LLWStringUtil::trim(item_label);
+
+ size_t found_iter = item_label.find(substring_trimmed);
+
+ if (found_iter != std::string::npos)
+ {
+ // find offset of matching text
+ cellp->highlightText(found_iter, substring_trimmed.size());
+ selectItem(item, -1, FALSE);
+
+ found++;
+
+ if (!mAllowMultipleSelection)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if (focus && found != 0)
+ {
+ mNeedsScroll = true;
+ }
+
+ if (mCommitOnSelectionChange)
+ {
+ commitIfChanged();
+ }
+
+ return found;
+}
+
const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const
{
LLScrollListItem* item;
@@ -1912,6 +1990,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id));
+ registrar.add("Url.ReportAbuse", boost::bind(&LLScrollListCtrl::reportAbuse, id, is_group));
registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1975,6 +2054,15 @@ void LLScrollListCtrl::removeFriend(std::string id)
LLUrlAction::removeFriend(slurl);
}
+void LLScrollListCtrl::reportAbuse(std::string id, bool is_group)
+{
+ if (!is_group)
+ {
+ std::string slurl = "secondlife:///app/agent/" + id + "/about";
+ LLUrlAction::reportAbuse(slurl);
+ }
+}
+
void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
{
// open the resident's details or the group details
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 08134bbfc8..77d10fdec7 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -267,6 +267,14 @@ public:
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
+ // If multi select is on, select all element that include substring,
+ // otherwise select first match only.
+ // If focus is true will scroll to selection.
+ // Returns number of results.
+ // Note: at the moment search happens in one go and is expensive
+ U32 searchItems(const std::string& substring, bool case_sensitive = false, bool focus = true);
+ U32 searchItems(const LLWString& substring, bool case_sensitive = false, bool focus = true);
+
// DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue().
// "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
// has an associated, unique UUID, and only one of which can be selected at a time.
@@ -325,6 +333,7 @@ public:
// support right-click context menus for avatar/group lists
enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP };
void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; }
+ ContextMenuType getContextMenuType() { return mContextMenuType; }
// Overridden from LLView
/*virtual*/ void draw();
@@ -460,6 +469,7 @@ private:
static void sendIM(std::string id);
static void addFriend(std::string id);
static void removeFriend(std::string id);
+ static void reportAbuse(std::string id, bool is_group);
static void showNameDetails(std::string id, bool is_group);
static void copyNameToClipboard(std::string id, bool is_group);
static void copySLURLToClipboard(std::string id, bool is_group);
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index ee78b82429..ef7c8ec012 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -103,6 +103,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height);
up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
+ up_button_params.commit_on_capture_lost = true;
mUpBtn = LLUICtrlFactory::create<LLButton>(up_button_params);
addChild(mUpBtn);
@@ -111,6 +112,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height);
down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
+ down_button_params.commit_on_capture_lost = true;
mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params);
addChild(mDownBtn);
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 459fdcf2ae..0aa7a2d217 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -402,9 +402,13 @@ void LLTabContainer::draw()
S32 cur_scroll_pos = getScrollPos();
if (cur_scroll_pos > 0)
{
- S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
- if (!mIsVertical)
+ if (mIsVertical)
{
+ target_pixel_scroll = cur_scroll_pos * (BTN_HEIGHT + tabcntrv_pad);
+ }
+ else
+ {
+ S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
if (cur_scroll_pos == 0)
@@ -1189,13 +1193,15 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
sendChildToFront(mNextArrowBtn);
sendChildToFront(mJumpPrevArrowBtn);
sendChildToFront(mJumpNextArrowBtn);
-
+
+ updateMaxScrollPos();
+
if( select )
{
selectLastTab();
+ mScrollPos = mMaxScrollPos;
}
- updateMaxScrollPos();
}
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
@@ -2079,9 +2085,9 @@ void LLTabContainer::updateMaxScrollPos()
if( tab_total_height > available_height )
{
static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
- S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad);
+ S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad) - mNextArrowBtn->getRect().mBottom;
S32 additional_needed = tab_total_height - available_height_with_arrows;
- setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );
+ setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT + tabcntrv_pad) ) );
no_scroll = FALSE;
}
}
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 0dc99fdde6..7e4aaa53bf 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -163,6 +163,7 @@ LLTextBase::Params::Params()
font_shadow("font_shadow"),
wrap("wrap"),
trusted_content("trusted_content", true),
+ always_show_icons("always_show_icons", false),
use_ellipses("use_ellipses", false),
parse_urls("parse_urls", false),
force_urls_external("force_urls_external", false),
@@ -212,6 +213,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mClip(p.clip),
mClipPartial(p.clip_partial && !p.allow_scroll),
mTrustedContent(p.trusted_content),
+ mAlwaysShowIcons(p.always_show_icons),
mTrackEnd( p.track_end ),
mScrollIndex(-1),
mSelectionStart( 0 ),
@@ -448,8 +450,48 @@ void LLTextBase::drawSelectionBackground()
++rect_it)
{
LLRect selection_rect = *rect_it;
- selection_rect = *rect_it;
- selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ if (mScroller)
+ {
+ // If scroller is On content_display_rect has correct rect and safe to use as is
+ // Note: we might need to account for border
+ selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ }
+ else
+ {
+ // If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position
+ // and we have to acount for offset depending on position
+ S32 v_delta = 0;
+ S32 h_delta = 0;
+ switch (mVAlign)
+ {
+ case LLFontGL::TOP:
+ v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad;
+ break;
+ case LLFontGL::VCENTER:
+ v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2;
+ break;
+ case LLFontGL::BOTTOM:
+ v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom;
+ break;
+ default:
+ break;
+ }
+ switch (mHAlign)
+ {
+ case LLFontGL::LEFT:
+ h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad;
+ break;
+ case LLFontGL::HCENTER:
+ h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2;
+ break;
+ case LLFontGL::RIGHT:
+ h_delta = mVisibleTextRect.mRight - content_display_rect.mRight;
+ break;
+ default:
+ break;
+ }
+ selection_rect.translate(h_delta, v_delta);
+ }
gl_rect_2d(selection_rect, selection_color);
}
}
@@ -2007,6 +2049,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
+ registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));
registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
@@ -2116,7 +2159,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
- boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted()))
+ boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted() || mAlwaysShowIcons))
{
start = match.getStart();
end = match.getEnd()+1;
@@ -2141,7 +2184,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// add icon before url if need
- LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
+ LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted() || mAlwaysShowIcons);
if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
{
setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 2e2e1b9833..25f8fa1c2b 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -321,7 +321,8 @@ public:
parse_highlights,
clip,
clip_partial,
- trusted_content;
+ trusted_content,
+ always_show_icons;
Optional<S32> v_pad,
h_pad;
@@ -369,6 +370,8 @@ public:
virtual void onFocusReceived();
virtual void onFocusLost();
+ void setParseHTML(bool parse_html) { mParseHTML = parse_html; }
+
// LLSpellCheckMenuHandler overrides
/*virtual*/ bool getSpellCheck() const;
@@ -457,6 +460,8 @@ public:
void setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; }
bool getSkipLinkUnderline() { return mSkipLinkUnderline; }
+ void setParseURLs(bool parse_urls) { mParseHTML = parse_urls; }
+
void setPlainText(bool value) { mPlainText = value;}
bool getPlainText() const { return mPlainText; }
@@ -700,6 +705,8 @@ protected:
bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
bool mSkipTripleClick;
+ bool mAlwaysShowIcons;
+
bool mSkipLinkUnderline;
// support widgets
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 26702b2412..1a10d2fd1e 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -196,6 +196,7 @@ public:
const LLUUID& getSourceID() const { return mSourceID; }
const LLTextSegmentPtr getPreviousSegment() const;
+ const LLTextSegmentPtr getLastSegment() const;
void getSelectedSegments(segment_vec_t& segments) const;
void setShowContextMenu(bool show) { mShowContextMenu = show; }
diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp
index 538508b856..78049319bc 100644
--- a/indra/llui/lltextutil.cpp
+++ b/indra/llui/lltextutil.cpp
@@ -76,22 +76,6 @@ void LLTextUtil::textboxSetGreyedVal(LLTextBox *txtbox, const LLStyle::Params& n
txtbox->appendText(text.substr(greyed_begin + greyed_len), false, normal_style);
}
-const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str)
-{
- static const std::string PHONE_SEPARATOR = LLUI::getInstance()->mSettingGroups["config"]->getString("AvalinePhoneSeparator");
- static const S32 PHONE_PART_LEN = 2;
-
- static std::string formatted_phone_str;
- formatted_phone_str = phone_str;
- S32 separator_pos = (S32)(formatted_phone_str.size()) - PHONE_PART_LEN;
- for (; separator_pos >= PHONE_PART_LEN; separator_pos -= PHONE_PART_LEN)
- {
- formatted_phone_str.insert(separator_pos, PHONE_SEPARATOR);
- }
-
- return formatted_phone_str;
-}
-
bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted)
{
if (match == 0 || text_base == 0)
diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h
index a9c143e445..1adc3516f7 100644
--- a/indra/llui/lltextutil.h
+++ b/indra/llui/lltextutil.h
@@ -59,18 +59,6 @@ namespace LLTextUtil
const std::string& greyed);
/**
- * Formats passed phone number to be more human readable.
- *
- * It just divides the number on parts by two digits from right to left. The first left part
- * can have 2 or 3 digits, i.e. +44-33-33-44-55-66 or 12-34-56-78-90. Separator is set in
- * application settings (AvalinePhoneSeparator)
- *
- * @param[in] phone_str string with original phone number
- * @return reference to string with formatted phone number
- */
- const std::string& formatPhoneNumber(const std::string& phone_str);
-
- /**
* Adds icon before url if need.
*
* @param[in] match an object with results of matching
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 30dbd7248f..86b23c8c93 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -76,7 +76,8 @@ enum EDragAndDropType
DAD_WIDGET = 16,
DAD_PERSON = 17,
DAD_SETTINGS = 18,
- DAD_COUNT = 19, // number of types in this enum
+ DAD_MATERIAL = 19,
+ DAD_COUNT = 20, // number of types in this enum
};
// Reasons for drags to be denied.
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 84ea770a8d..8216046174 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -222,6 +222,15 @@ void LLUrlAction::removeFriend(std::string url)
}
}
+void LLUrlAction::reportAbuse(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/reportAbuse");
+ }
+}
+
void LLUrlAction::blockObject(std::string url)
{
std::string object_id = getObjectId(url);
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index 2d2a8dfef1..c2c576254d 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -82,6 +82,7 @@ public:
static void sendIM(std::string url);
static void addFriend(std::string url);
static void removeFriend(std::string url);
+ static void reportAbuse(std::string url);
static void blockObject(std::string url);
static void unblockObject(std::string url);
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 32f0fa14c4..5fbb88400b 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -199,4 +199,10 @@ if (SDL_FOUND)
endif (SDL_FOUND)
target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
+
+if (DARWIN)
+ include(CMakeFindFrameworks)
+ find_library(CARBON_LIBRARY Carbon)
+ target_link_libraries(llwindow ${CARBON_LIBRARY})
+endif (DARWIN)
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index 12a6baa3e6..81e938edbe 100644
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -229,7 +229,7 @@ S32 LLDXHardware::getMBVideoMemoryViaWMI()
}
//Getting the version of graphics controller driver via WMI
-std::string LLDXHardware::getDriverVersionWMI()
+std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
{
std::string mDriverVersion;
HRESULT hrCoInitialize = S_OK;
@@ -325,15 +325,68 @@ std::string LLDXHardware::getDriverVersionWMI()
{
break; // If quantity less then 1.
}
+
+ if (vendor != GPU_ANY)
+ {
+ VARIANT vtCaptionProp;
+ // Might be preferable to check "AdapterCompatibility" here instead of caption.
+ hr = pclsObj->Get(L"Caption", 0, &vtCaptionProp, 0, 0);
+
+ if (FAILED(hr))
+ {
+ LL_WARNS("AppInit") << "Query for Caption property failed." << " Error code = 0x" << hr << LL_ENDL;
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return std::string(); // Program has failed.
+ }
+
+ // use characters in the returned driver version
+ BSTR caption(vtCaptionProp.bstrVal);
+
+ //convert BSTR to std::string
+ std::wstring ws(caption, SysStringLen(caption));
+ std::string caption_str(ws.begin(), ws.end());
+ LLStringUtil::toLower(caption_str);
+
+ bool found = false;
+ switch (vendor)
+ {
+ case GPU_INTEL:
+ found = caption_str.find("intel") != std::string::npos;
+ break;
+ case GPU_NVIDIA:
+ found = caption_str.find("nvidia") != std::string::npos;
+ break;
+ case GPU_AMD:
+ found = caption_str.find("amd") != std::string::npos
+ || caption_str.find("ati ") != std::string::npos
+ || caption_str.find("radeon") != std::string::npos;
+ break;
+ default:
+ break;
+ }
- VARIANT vtProp;
+ if (found)
+ {
+ VariantClear(&vtCaptionProp);
+ }
+ else
+ {
+ VariantClear(&vtCaptionProp);
+ pclsObj->Release();
+ continue;
+ }
+ }
- // Get the value of the Name property
- hr = pclsObj->Get(L"DriverVersion", 0, &vtProp, 0, 0);
+ VARIANT vtVersionProp;
+
+ // Get the value of the DriverVersion property
+ hr = pclsObj->Get(L"DriverVersion", 0, &vtVersionProp, 0, 0);
if (FAILED(hr))
{
- LL_WARNS("AppInit") << "Query for name property failed." << " Error code = 0x" << hr << LL_ENDL;
+ LL_WARNS("AppInit") << "Query for DriverVersion property failed." << " Error code = 0x" << hr << LL_ENDL;
pSvc->Release();
pLoc->Release();
CoUninitialize();
@@ -341,7 +394,7 @@ std::string LLDXHardware::getDriverVersionWMI()
}
// use characters in the returned driver version
- BSTR driverVersion(vtProp.bstrVal);
+ BSTR driverVersion(vtVersionProp.bstrVal);
//convert BSTR to std::string
std::wstring ws(driverVersion, SysStringLen(driverVersion));
@@ -354,10 +407,19 @@ std::string LLDXHardware::getDriverVersionWMI()
}
else if (mDriverVersion != str)
{
- LL_WARNS("DriverVersion") << "Different versions of drivers. Version of second driver : " << str << LL_ENDL;
+ if (vendor == GPU_ANY)
+ {
+ // Expected from systems with gpus from different vendors
+ LL_INFOS("DriverVersion") << "Multiple video drivers detected. Version of second driver: " << str << LL_ENDL;
+ }
+ else
+ {
+ // Not Expected!
+ LL_WARNS("DriverVersion") << "Multiple video drivers detected from same vendor. Version of second driver : " << str << LL_ENDL;
+ }
}
- VariantClear(&vtProp);
+ VariantClear(&vtVersionProp);
pclsObj->Release();
}
diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h
index 1cb687e3b6..9cec3e2f1b 100644
--- a/indra/llwindow/lldxhardware.h
+++ b/indra/llwindow/lldxhardware.h
@@ -88,7 +88,15 @@ public:
// vram_only TRUE does a "light" probe.
BOOL getInfo(BOOL vram_only);
- std::string getDriverVersionWMI();
+ // WMI can return multiple GPU drivers
+ // specify which one to output
+ typedef enum {
+ GPU_INTEL,
+ GPU_NVIDIA,
+ GPU_AMD,
+ GPU_ANY
+ } EGPUVendor;
+ std::string getDriverVersionWMI(EGPUVendor vendor);
S32 getVRAM() const { return mVRAM; }
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index 5404ac50e5..e65cc7563e 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -148,6 +148,22 @@ void LLKeyboard::addKeyName(KEY key, const std::string& name)
sNamesToKeys[nameuc] = key;
}
+void LLKeyboard::resetKeyDownAndHandle()
+{
+ MASK mask = currentMask(FALSE);
+ for (S32 i = 0; i < KEY_COUNT; i++)
+ {
+ if (mKeyLevel[i])
+ {
+ mKeyDown[i] = FALSE;
+ mKeyLevel[i] = FALSE;
+ mKeyUp[i] = TRUE;
+ mCurTranslatedKey = (KEY)i;
+ mCallbacks->handleTranslatedKeyUp(i, mask);
+ }
+ }
+}
+
// BUG this has to be called when an OS dialog is shown, otherwise modifier key state
// is wrong because the keyup event is never received by the main window. JC
void LLKeyboard::resetKeys()
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index 36bd8bcbed..fb1ae10f50 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -58,7 +58,8 @@ public:
LLKeyboard();
virtual ~LLKeyboard();
- void resetKeys();
+ void resetKeyDownAndHandle();
+ void resetKeys();
F32 getCurKeyElapsedTime() { return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; }
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 8d064ec86c..9fed57ba53 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -261,6 +261,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAColorSize, 24,
+ NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core,
0
};
@@ -500,14 +501,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
// e.g. OS Window for upload something or Input Window...
// mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit)
mModifiers = [theEvent modifierFlags];
+ unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
+ bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch);
- bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, [[theEvent characters] characterAtIndex:0]);
- unichar ch;
if (acceptsText &&
!mMarkedTextAllowed &&
!(mModifiers & (NSControlKeyMask | NSCommandKeyMask)) && // commands don't invoke InputWindow
![(LLAppDelegate*)[NSApp delegate] romanScript] &&
- (ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]) > ' ' &&
+ ch > ' ' &&
ch != NSDeleteCharacter &&
(ch < 0xF700 || ch > 0xF8FF)) // 0xF700-0xF8FF: reserved for function keys on the keyboard(from NSEvent.h)
{
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index f895c17643..5ec9b017cf 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -100,13 +100,13 @@ const unsigned short *copyFromPBoard()
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
NSCursor *cursor =
[[[NSCursor alloc]
initWithImage:
[[[NSImage alloc] initWithContentsOfFile:
- [NSString stringWithFormat:@"%s", fullpath]
+ [NSString stringWithUTF8String:fullpath]
]autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY)
]retain];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 4bcb9b3aef..02941f2a3e 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -621,8 +621,6 @@ void LLWindowMacOSX::getMouseDeltas(float* delta)
BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync)
{
- BOOL glNeedsInit = FALSE;
-
mFullscreen = fullscreen;
if (mWindow == NULL)
@@ -637,9 +635,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync);
mContext = getCGLContextObj(mGLView);
- // Since we just created the context, it needs to be set up.
- glNeedsInit = TRUE;
-
gGLManager.mVRAM = getVramSize(mGLView);
}
@@ -1676,7 +1671,7 @@ void LLWindowMacOSX::hideCursor()
void LLWindowMacOSX::showCursor()
{
- if(mCursorHidden)
+ if(mCursorHidden || !isCGCursorVisible())
{
// LL_INFOS() << "showCursor: showing" << LL_ENDL;
mCursorHidden = FALSE;
@@ -1731,9 +1726,7 @@ void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
{
if(mWindow != NULL)
{
- CFStringRef string = NULL;
-
- string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
+ CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
}
}
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 201330137f..91d98fe0bf 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -64,6 +64,7 @@
#include <d3d9.h>
#include <dxgi1_4.h>
+#include <timeapi.h>
// Require DirectInput version 8
#define DIRECTINPUT_VERSION 0x0800
@@ -414,6 +415,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
HWND mWindowHandle = NULL;
HDC mhDC = 0;
+ // best guess at available video memory in MB
std::atomic<U32> mAvailableVRAM;
IDXGIAdapter3* mDXGIAdapter = nullptr;
@@ -898,21 +900,20 @@ void LLWindowWin32::close()
// Restore gamma to the system values.
restoreGamma();
- if (mhDC)
- {
- if (!ReleaseDC(mWindowHandle, mhDC))
- {
- LL_WARNS("Window") << "Release of ghDC failed" << LL_ENDL;
- }
- mhDC = NULL;
- }
-
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
mWindowThread->post([=]()
{
if (IsWindow(mWindowHandle))
{
+ if (mhDC)
+ {
+ if (!ReleaseDC(mWindowHandle, mhDC))
+ {
+ LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL;
+ }
+ }
+
// Make sure we don't leave a blank toolbar button.
ShowWindow(mWindowHandle, SW_HIDE);
@@ -938,6 +939,7 @@ void LLWindowWin32::close()
// Even though the above lambda might not yet have run, we've already
// bound mWindowHandle into it by value, which should suffice for the
// operations we're asking. That's the last time WE should touch it.
+ mhDC = NULL;
mWindowHandle = NULL;
mWindowThread->close();
}
@@ -1371,8 +1373,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO
attrib_list[cur_attrib++] = WGL_DEPTH_BITS_ARB;
attrib_list[cur_attrib++] = 24;
- attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB;
- attrib_list[cur_attrib++] = 8;
+ //attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB; //stencil buffer is deprecated (performance penalty)
+ //attrib_list[cur_attrib++] = 8;
attrib_list[cur_attrib++] = WGL_DRAW_TO_WINDOW_ARB;
attrib_list[cur_attrib++] = GL_TRUE;
@@ -1530,12 +1532,10 @@ const S32 max_format = (S32)num_formats - 1;
{
wglDeleteContext (mhRC); // Release The Rendering Context
mhRC = 0; // Zero The Rendering Context
-
}
- ReleaseDC (mWindowHandle, mhDC); // Release The Device Context
- mhDC = 0; // Zero The Device Context
}
+ // will release and recreate mhDC, mWindowHandle
recreateWindow(window_rect, dw_ex_style, dw_style);
RECT rect;
@@ -1647,8 +1647,6 @@ const S32 max_format = (S32)num_formats - 1;
return FALSE;
}
- LL_PROFILER_GPU_CONTEXT
-
if (!gGLManager.initGL())
{
OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK);
@@ -1680,12 +1678,15 @@ const S32 max_format = (S32)num_formats - 1;
swapBuffers();
}
+ LL_PROFILER_GPU_CONTEXT;
+
return TRUE;
}
void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style)
{
- auto oldHandle = mWindowHandle;
+ auto oldWindowHandle = mWindowHandle;
+ auto oldDCHandle = mhDC;
// zero out mWindowHandle and mhDC before destroying window so window
// thread falls back to peekmessage
@@ -1697,7 +1698,8 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
auto window_work =
[this,
self=mWindowThread,
- oldHandle,
+ oldWindowHandle,
+ oldDCHandle,
// bind CreateWindowEx() parameters by value instead of
// back-referencing LLWindowWin32 members
windowClassName=mWindowClassName,
@@ -1713,11 +1715,20 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
self->mWindowHandle = 0;
self->mhDC = 0;
- // important to call DestroyWindow() from the window thread
- if (oldHandle && !destroy_window_handler(oldHandle))
+ if (oldWindowHandle)
{
- LL_WARNS("Window") << "Failed to properly close window before recreating it!"
- << LL_ENDL;
+ if (oldDCHandle && !ReleaseDC(oldWindowHandle, oldDCHandle))
+ {
+ LL_WARNS("Window") << "Failed to ReleaseDC" << LL_ENDL;
+ }
+
+ // important to call DestroyWindow() from the window thread
+ if (!destroy_window_handler(oldWindowHandle))
+ {
+
+ LL_WARNS("Window") << "Failed to properly close window before recreating it!"
+ << LL_ENDL;
+ }
}
auto handle = CreateWindowEx(dw_ex_style,
@@ -1755,7 +1766,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
};
// But how we pass window_work to the window thread depends on whether we
// already have a window handle.
- if (! oldHandle)
+ if (!oldWindowHandle)
{
// Pass window_work using the WorkQueue: without an existing window
// handle, the window thread can't call GetMessage().
@@ -1768,7 +1779,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
// PostMessage(oldHandle) because oldHandle won't be destroyed until
// the window thread has retrieved and executed window_work.
LL_DEBUGS("Window") << "posting window_work to message queue" << LL_ENDL;
- mWindowThread->Post(oldHandle, window_work);
+ mWindowThread->Post(oldWindowHandle, window_work);
}
auto future = promise.get_future();
@@ -1833,6 +1844,7 @@ void* LLWindowWin32::createSharedContext()
void LLWindowWin32::makeContextCurrent(void* contextPtr)
{
wglMakeCurrent(mhDC, (HGLRC) contextPtr);
+ LL_PROFILER_GPU_CONTEXT;
}
void LLWindowWin32::destroySharedContext(void* contextPtr)
@@ -3081,8 +3093,20 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
if (raw->header.dwType == RIM_TYPEMOUSE)
{
LLMutexLock lock(&window_imp->mRawMouseMutex);
- window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
- window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
+
+ S32 speed;
+ const S32 DEFAULT_SPEED(10);
+ SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
+ if (speed == DEFAULT_SPEED)
+ {
+ window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
+ window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
+ }
+ else
+ {
+ window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
+ window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
+ }
}
}
}
@@ -3598,10 +3622,13 @@ void LLWindowWin32::swapBuffers()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32;
ASSERT_MAIN_THREAD();
- glFlush(); //superstitious flush for maybe frame stall removal?
+ {
+ LL_PROFILE_GPU_ZONE("flush");
+ glFlush(); //superstitious flush for maybe frame stall removal?
+ }
SwapBuffers(mhDC);
- LL_PROFILER_GPU_COLLECT
+ LL_PROFILER_GPU_COLLECT;
}
@@ -4727,44 +4754,68 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
LL_PROFILE_ZONE_SCOPED;
if (mDXGIAdapter != nullptr)
{
+ // NOTE: what lies below is hand wavy math based on compatibility testing and observation against a variety of hardware
+ // It doesn't make sense, but please don't refactor it to make sense. -- davep
+
DXGI_QUERY_VIDEO_MEMORY_INFO info;
mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info);
- // try to use no more than the available reserve minus 10%
- U32 target = info.Budget / 1024 / 1024;
+#if 0 // debug 0 budget and 0 CU
+ info.Budget = 0;
+ info.CurrentUsage = 0;
+#endif
+
+ U32 budget_mb = info.Budget / 1024 / 1024;
+ U32 afr_mb = info.AvailableForReservation / 1024 / 1024;
+ // correct for systems that misreport budget
+ if (budget_mb == 0)
+ {
+ // fall back to available for reservation clamped between 512MB and 2GB
+ budget_mb = llclamp(afr_mb, (U32) 512, (U32) 2048);
+ }
+
+ U32 cu_mb = info.CurrentUsage / 1024 / 1024;
+
+ // get an estimated usage based on texture bytes allocated
+ U32 eu_mb = LLImageGL::getTextureBytesAllocated() * 2 / 1024 / 1024;
+
+ if (cu_mb == 0)
+ { // current usage is sometimes unreliable on Intel GPUs, fall back to estimated usage
+ cu_mb = llmax((U32)1, eu_mb);
+ }
+ F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb;
+
+ U32 target_mb = info.Budget / 1024 / 1024;
- // EXPERIMENTAL
- // Trying to zero in on a good target usage, code here should be tuned against observed behavior
- // of various hardware.
- if (target > 4096) // if 4GB are installed, try to leave 2GB free
+ if (target_mb > 4096) // if 4GB are installed, try to leave 2GB free
{
- target -= 2048;
+ target_mb -= 2048;
}
else // if less than 4GB are installed, try not to use more than half of it
{
- target /= 2;
+ target_mb /= 2;
}
- U32 used_vram = info.CurrentUsage / 1024 / 1024;
-
- mAvailableVRAM = used_vram < target ? target - used_vram : 0;
+ mAvailableVRAM = cu_mb < target_mb ? target_mb - cu_mb : 0;
LL_INFOS("Window") << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024
<< "\nBudget: " << info.Budget / 1024 / 1024
<< "\nCR: " << info.CurrentReservation / 1024 / 1024
- << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;
+ << "\nCU: " << info.CurrentUsage / 1024 / 1024
+ << "\nEU: " << eu_mb << llformat(" (%.2f)", eu_error)
+ << "\nTU: " << target_mb
+ << "\nAM: " << mAvailableVRAM << LL_ENDL;
- mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info);
+ /*mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info);
LL_INFOS("Window") << "\nNon-Local\nAFR: " << info.AvailableForReservation / 1024 / 1024
<< "\nBudget: " << info.Budget / 1024 / 1024
<< "\nCR: " << info.CurrentReservation / 1024 / 1024
- << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;
+ << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;*/
}
else if (mD3DDevice != NULL)
{ // fallback to D3D9
mAvailableVRAM = mD3DDevice->GetAvailableTextureMem() / 1024 / 1024;
}
-
}
void LLWindowWin32::LLWindowWin32Thread::run()
@@ -4774,6 +4825,14 @@ void LLWindowWin32::LLWindowWin32Thread::run()
initDX();
+ //as good a place as any to up the MM timer resolution (see ms_sleep)
+ //attempt to set timer resolution to 1ms
+ TIMECAPS tc;
+ if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOERROR)
+ {
+ timeBeginPeriod(llclamp((U32) 1, tc.wPeriodMin, tc.wPeriodMax));
+ }
+
while (! getQueue().done())
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32;
diff --git a/indra/mac_crash_logger/README.txt b/indra/mac_crash_logger/README.txt
deleted file mode 100644
index 6932a8d9c3..0000000000
--- a/indra/mac_crash_logger/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-This component is no longer used in Linden Lab builds.
-Change requests to support continued use by open source
-builds are welcome.
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index ea70e21414..43d3a32e64 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -34,6 +34,7 @@
#include "llplugininstance.h"
#include "llpluginmessage.h"
#include "llpluginmessageclasses.h"
+#include "llstring.h"
#include "volume_catcher.h"
#include "media_plugin_base.h"
@@ -55,7 +56,7 @@ private:
bool init();
void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height);
- void onCustomSchemeURLCallback(std::string url);
+ void onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect);
void onConsoleMessageCallback(std::string message, std::string source, int line);
void onStatusMessageCallback(std::string value);
void onTitleChangeCallback(std::string title);
@@ -299,11 +300,18 @@ void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target)
////////////////////////////////////////////////////////////////////////////////
//
-void MediaPluginCEF::onCustomSchemeURLCallback(std::string url)
+void MediaPluginCEF::onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
- message.setValue("uri", url);
- message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to
+ message.setValue("uri", url);
+
+ // indicate if this interaction was from a user click (okay on a SLAPP) or
+ // via a navigation (e.g. a data URL - see SL-18151) (not okay on a SLAPP)
+ const std::string nav_type = user_gesture ? "clicked" : "navigated";
+
+ message.setValue("nav_type", nav_type);
+ message.setValueBoolean("is_redirect", is_redirect);
+
sendMessage(message);
}
@@ -592,7 +600,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
// event callbacks from Dullahan
mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
- mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
+ mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
@@ -616,9 +624,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
// dir as the executable that loaded it (SLPlugin.exe). The code in
// Dullahan that tried to figure out the location automatically uses
// the location of the exe which isn't helpful so we tell it explicitly.
- char cur_dir_str[MAX_PATH];
- GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
- settings.host_process_path = std::string(cur_dir_str);
+ std::vector<wchar_t> buffer(MAX_PATH + 1);
+ GetCurrentDirectoryW(MAX_PATH, &buffer[0]);
+ settings.host_process_path = ll_convert_wide_to_string(&buffer[0]);
#endif
settings.accept_language_list = mHostLanguage;
diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
index 1afe25e9a1..89144922cc 100644
--- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
+++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
@@ -73,6 +73,7 @@ private:
static void display(void* data, void* id);
/*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */;
+ void setDurationDirty();
static void eventCallbacks(const libvlc_event_t* event, void* ptr);
@@ -93,8 +94,8 @@ private:
bool mIsLooping;
- float mCurTime;
- float mDuration;
+ F64 mCurTime;
+ F64 mDuration;
EStatus mVlcStatus;
};
@@ -214,6 +215,19 @@ void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom)
}
////////////////////////////////////////////////////////////////////////////////
+// *virtual*
+void MediaPluginLibVLC::setDurationDirty()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
+
+ message.setValueReal("current_time", mCurTime);
+ message.setValueReal("duration", mDuration);
+ message.setValueReal("current_rate", 1.0f);
+
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
{
@@ -233,6 +247,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f;
parent->mVlcStatus = STATUS_PLAYING;
parent->setVolumeVLC();
+ parent->setDurationDirty();
break;
case libvlc_MediaPlayerPaused:
@@ -245,6 +260,8 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerEndReached:
parent->mVlcStatus = STATUS_DONE;
+ parent->mCurTime = parent->mDuration;
+ parent->setDurationDirty();
break;
case libvlc_MediaPlayerEncounteredError:
@@ -253,6 +270,11 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerTimeChanged:
parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f;
+ if (parent->mVlcStatus == STATUS_DONE && libvlc_media_player_is_playing(parent->mLibVLCMediaPlayer))
+ {
+ parent->mVlcStatus = STATUS_PLAYING;
+ }
+ parent->setDurationDirty();
break;
case libvlc_MediaPlayerPositionChanged:
@@ -260,6 +282,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerLengthChanged:
parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f;
+ parent->setDurationDirty();
break;
case libvlc_MediaPlayerTitleChanged:
@@ -562,7 +585,24 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
mTextureWidth = texture_width;
mTextureHeight = texture_height;
+ libvlc_time_t time = 1000.0 * mCurTime;
+
playMedia();
+
+ if (mLibVLCMediaPlayer)
+ {
+ libvlc_media_player_set_time(mLibVLCMediaPlayer, time);
+ time = libvlc_media_player_get_time(mLibVLCMediaPlayer);
+ if (time < 0)
+ {
+ // -1 if there is no media
+ mCurTime = 0;
+ }
+ else
+ {
+ mCurTime = (F64)time / 1000.0;
+ }
+ }
};
};
@@ -594,6 +634,13 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
{
if (mLibVLCMediaPlayer)
{
+ if (mVlcStatus == STATUS_DONE && !libvlc_media_player_is_playing(mLibVLCMediaPlayer))
+ {
+ // stop or vlc will ignore 'play', it will just
+ // make an MediaPlayerEndReached event even if
+ // seek was used
+ libvlc_media_player_stop(mLibVLCMediaPlayer);
+ }
libvlc_media_player_play(mLibVLCMediaPlayer);
}
}
@@ -606,15 +653,32 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
}
else if (message_name == "seek")
{
- if (mDuration > 0)
- {
- F64 normalized_offset = message_in.getValueReal("time") / mDuration;
- libvlc_media_player_set_position(mLibVLCMediaPlayer, normalized_offset);
- }
+ if (mLibVLCMediaPlayer)
+ {
+ libvlc_time_t time = 1000.0 * message_in.getValueReal("time");
+ libvlc_media_player_set_time(mLibVLCMediaPlayer, time);
+ time = libvlc_media_player_get_time(mLibVLCMediaPlayer);
+ if (time < 0)
+ {
+ // -1 if there is no media
+ mCurTime = 0;
+ }
+ else
+ {
+ mCurTime = (F64)time / 1000.0;
+ }
+
+ if (!libvlc_media_player_is_playing(mLibVLCMediaPlayer))
+ {
+ // if paused, won't trigger update, update now
+ setDurationDirty();
+ }
+ }
}
else if (message_name == "set_loop")
{
- mIsLooping = true;
+ bool loop = message_in.getValueBoolean("loop");
+ mIsLooping = loop;
}
else if (message_name == "set_volume")
{
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f13ce85495..374db7fdf8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -56,7 +56,8 @@ include(UnixInstall)
include(ViewerMiscLibs)
include(ViewerManager)
include(VisualLeakDetector)
-include(ZLIB)
+include(VulkanGltf)
+include(ZLIBNG)
include(URIPARSER)
if (NOT HAVOK_TPV)
@@ -187,6 +188,7 @@ set(viewer_SOURCE_FILES
lldrawpoolbump.cpp
lldrawpoolground.cpp
lldrawpoolmaterials.cpp
+ lldrawpoolpbropaque.cpp
lldrawpoolsimple.cpp
lldrawpoolsky.cpp
lldrawpoolterrain.cpp
@@ -206,6 +208,7 @@ set(viewer_SOURCE_FILES
llfasttimerview.cpp
llfavoritesbar.cpp
llfeaturemanager.cpp
+ llfetchedgltfmaterial.cpp
llfilepicker.cpp
llfilteredwearablelist.cpp
llfirstuse.cpp
@@ -234,12 +237,14 @@ set(viewer_SOURCE_FILES
llfloatercamera.cpp
llfloatercamerapresets.cpp
llfloaterchatvoicevolume.cpp
+ llfloaterclassified.cpp
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
+ llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
llfloaterenvironmentadjust.cpp
@@ -295,9 +300,11 @@ set(viewer_SOURCE_FILES
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
+ llfloaterprofile.cpp
llfloaterpreference.cpp
llfloaterpreferenceviewadvanced.cpp
llfloaterpreviewtrash.cpp
+ llfloaterprofiletexture.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
@@ -329,7 +336,6 @@ set(viewer_SOURCE_FILES
llfloatervoiceeffect.cpp
llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
- llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
@@ -341,6 +347,7 @@ set(viewer_SOURCE_FILES
llgesturemgr.cpp
llgiveinventory.cpp
llglsandbox.cpp
+ llgltfmateriallist.cpp
llgroupactions.cpp
llgroupiconctrl.cpp
llgrouplist.cpp
@@ -390,6 +397,7 @@ set(viewer_SOURCE_FILES
lllistcontextmenu.cpp
lllistview.cpp
lllocalbitmaps.cpp
+ lllocalgltfmaterials.cpp
lllocationhistory.cpp
lllocationinputctrl.cpp
lllogchat.cpp
@@ -402,6 +410,7 @@ set(viewer_SOURCE_FILES
llmaniptranslate.cpp
llmarketplacefunctions.cpp
llmarketplacenotifications.cpp
+ llmaterialeditor.cpp
llmaterialmgr.cpp
llmediactrl.cpp
llmediadataclient.cpp
@@ -475,7 +484,6 @@ set(viewer_SOURCE_FILES
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
- llpanelme.cpp
llpanelnearbymedia.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
@@ -485,8 +493,6 @@ set(viewer_SOURCE_FILES
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
- llpanelpick.cpp
- llpanelpicks.cpp
llpanelplaceinfo.cpp
llpanelplaceprofile.cpp
llpanelplaces.cpp
@@ -495,6 +501,8 @@ set(viewer_SOURCE_FILES
llpanelpresetspulldown.cpp
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
+ llpanelprofileclassifieds.cpp
+ llpanelprofilepicks.cpp
llpanelsnapshot.cpp
llpanelsnapshotinventory.cpp
llpanelsnapshotlocal.cpp
@@ -544,6 +552,8 @@ set(viewer_SOURCE_FILES
llproductinforequest.cpp
llprogressview.cpp
llrecentpeople.cpp
+ llreflectionmap.cpp
+ llreflectionmapmanager.cpp
llregioninfomodel.cpp
llregionposition.cpp
llremoteparcelrequest.cpp
@@ -600,6 +610,7 @@ set(viewer_SOURCE_FILES
lltextureinfodetails.cpp
lltexturestats.cpp
lltextureview.cpp
+ lltinygltfhelper.cpp
lltoast.cpp
lltoastalertpanel.cpp
lltoastgroupnotifypanel.cpp
@@ -656,6 +667,7 @@ set(viewer_SOURCE_FILES
llviewercontrol.cpp
llviewercontrollistener.cpp
llviewerdisplay.cpp
+ llviewerdisplayname.cpp
llviewerfloaterreg.cpp
llviewerfoldertype.cpp
llviewergenericmessage.cpp
@@ -821,6 +833,7 @@ set(viewer_HEADER_FILES
lldrawpoolavatar.h
lldrawpoolbump.h
lldrawpoolmaterials.h
+ lldrawpoolpbropaque.h
lldrawpoolground.h
lldrawpoolsimple.h
lldrawpoolsky.h
@@ -841,6 +854,7 @@ set(viewer_HEADER_FILES
llfasttimerview.h
llfavoritesbar.h
llfeaturemanager.h
+ llfetchedgltfmaterial.h
llfilepicker.h
llfilteredwearablelist.h
llfirstuse.h
@@ -869,12 +883,14 @@ set(viewer_HEADER_FILES
llfloatercamerapresets.h
llfloatercamera.h
llfloaterchatvoicevolume.h
+ llfloaterclassified.h
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
+ llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
llfloaterenvironmentadjust.h
@@ -933,9 +949,11 @@ set(viewer_HEADER_FILES
llfloaterpay.h
llfloaterperms.h
llfloaterpostprocess.h
+ llfloaterprofile.h
llfloaterpreference.h
llfloaterpreferenceviewadvanced.h
llfloaterpreviewtrash.h
+ llfloaterprofiletexture.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
@@ -967,7 +985,6 @@ set(viewer_HEADER_FILES
llfloatervoiceeffect.h
llfloatervoicevolume.h
llfloaterwebcontent.h
- llfloaterwebprofile.h
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
@@ -978,6 +995,7 @@ set(viewer_HEADER_FILES
llgesturelistener.h
llgesturemgr.h
llgiveinventory.h
+ llgltfmateriallist.h
llgroupactions.h
llgroupiconctrl.h
llgrouplist.h
@@ -1026,6 +1044,7 @@ set(viewer_HEADER_FILES
lllistcontextmenu.h
lllistview.h
lllocalbitmaps.h
+ lllocalgltfmaterials.h
lllocationhistory.h
lllocationinputctrl.h
lllogchat.h
@@ -1038,6 +1057,7 @@ set(viewer_HEADER_FILES
llmaniptranslate.h
llmarketplacefunctions.h
llmarketplacenotifications.h
+ llmaterialeditor.h
llmaterialmgr.h
llmediactrl.h
llmediadataclient.h
@@ -1103,7 +1123,6 @@ set(viewer_HEADER_FILES
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
- llpanelme.h
llpanelnearbymedia.h
llpanelobject.h
llpanelobjectinventory.h
@@ -1113,8 +1132,6 @@ set(viewer_HEADER_FILES
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
- llpanelpick.h
- llpanelpicks.h
llpanelplaceinfo.h
llpanelplaceprofile.h
llpanelplaces.h
@@ -1123,6 +1140,8 @@ set(viewer_HEADER_FILES
llpanelpresetspulldown.h
llpanelprimmediacontrols.h
llpanelprofile.h
+ llpanelprofileclassifieds.h
+ llpanelprofilepicks.h
llpanelsnapshot.h
llpanelteleporthistory.h
llpaneltiptoast.h
@@ -1167,6 +1186,8 @@ set(viewer_HEADER_FILES
llproductinforequest.h
llprogressview.h
llrecentpeople.h
+ llreflectionmap.h
+ llreflectionmapmanager.h
llregioninfomodel.h
llregionposition.h
llremoteparcelrequest.h
@@ -1227,6 +1248,7 @@ set(viewer_HEADER_FILES
lltextureinfodetails.h
lltexturestats.h
lltextureview.h
+ lltinygltfhelper.h
lltoast.h
lltoastalertpanel.h
lltoastgroupnotifypanel.h
@@ -1285,6 +1307,7 @@ set(viewer_HEADER_FILES
llviewercontrol.h
llviewercontrollistener.h
llviewerdisplay.h
+ llviewerdisplayname.h
llviewerfloaterreg.h
llviewerfoldertype.h
llviewergenericmessage.h
@@ -1667,18 +1690,23 @@ set_source_files_properties(${viewer_XUI_FILES}
list(APPEND viewer_SOURCE_FILES ${viewer_XUI_FILES})
+file(GLOB_RECURSE viewer_SHADER_FILES LIST_DIRECTORIES TRUE
+ ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/shaders/*.glsl)
+source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/shaders PREFIX "Shaders" FILES ${viewer_SHADER_FILES})
+set_source_files_properties(${viewer_SHADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+list(APPEND viewer_SOURCE_FILES ${viewer_SHADER_FILES})
+
+
set(viewer_APPSETTINGS_FILES
app_settings/anim.ini
app_settings/cmd_line.xml
app_settings/commands.xml
app_settings/grass.xml
- app_settings/high_graphics.xml
app_settings/ignorable_dialogs.xml
app_settings/key_bindings.xml
app_settings/keywords_lsl_default.xml
app_settings/logcontrol.xml
- app_settings/low_graphics.xml
- app_settings/mid_graphics.xml
app_settings/settings.xml
app_settings/settings_crash_behavior.xml
app_settings/settings_files.xml
@@ -1686,7 +1714,6 @@ set(viewer_APPSETTINGS_FILES
app_settings/std_bump.ini
app_settings/toolbars.xml
app_settings/trees.xml
- app_settings/ultra_graphics.xml
app_settings/viewerart.xml
${CMAKE_SOURCE_DIR}/../etc/message.xml
${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
@@ -1841,10 +1868,6 @@ if (WINDOWS)
winmm_shim
)
- if (NOT USE_BUGSPLAT)
- LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger)
- endif (NOT USE_BUGSPLAT)
-
if (ADDRESS_SIZE EQUAL 64)
list(APPEND COPY_INPUT_DEPENDENCIES
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll
@@ -2009,14 +2032,14 @@ endif (WINDOWS)
#
# We generally want the newest version of the library to provide all symbol
# resolution. To that end, when using static archives, the *_PRELOAD_ARCHIVES
-# variables, PNG_PRELOAD_ARCHIVES and ZLIB_PRELOAD_ARCHIVES, get the archives
+# variables, PNG_PRELOAD_ARCHIVES and ZLIBNG_PRELOAD_ARCHIVES, get the archives
# dumped into the target binary and runtime lookup will find the most
# modern version.
target_link_libraries(${VIEWER_BINARY_NAME}
${LEGACY_STDIO_LIBS}
${PNG_PRELOAD_ARCHIVES}
- ${ZLIB_PRELOAD_ARCHIVES}
+ ${ZLIBNG_PRELOAD_ARCHIVES}
${URIPARSER_PRELOAD_ARCHIVES}
${GOOGLE_PERFTOOLS_LIBRARIES}
${LLAUDIO_LIBRARIES}
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 09a7391e4e..66ce77b7ea 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.1
+7.0.0
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index dd2b656ce3..e16a5c7e76 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -55,7 +55,7 @@
<key>debugsession</key>
<map>
<key>desc</key>
- <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string>
+ <string>Run as if RenderDebugGLSession is TRUE, but log errors until end of session.</string>
<key>map-to</key>
<string>DebugSession</string>
</map>
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 3dfe3f6634..2644f5f449 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -167,10 +167,8 @@
icon="Command_Picks_Icon"
label_ref="Command_Picks_Label"
tooltip_ref="Command_Picks_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="picks"
- is_running_function="Floater.IsOpen"
- is_running_parameters="picks"
+ execute_function="Avatar.TogglePicks"
+ is_running_function="Avatar.IsPicksTabOpen"
/>
<command name="places"
available_in_toybox="true"
diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
deleted file mode 100644
index f64937f443..0000000000
--- a/indra/newview/app_settings/high_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.9"/>
- <!--Short Range-->
- <RenderFarClip value="128"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="9"/>
- <!--Low number-->
- <RenderMaxPartCount value="4096"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="2"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="2"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="20"/>
- <RenderAvatarMaxComplexity value="350000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1250.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="TRUE"/>
- <!--Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--Sun Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml
index 55babc88bc..8d5349550f 100644
--- a/indra/newview/app_settings/key_bindings.xml
+++ b/indra/newview/app_settings/key_bindings.xml
@@ -85,7 +85,6 @@
<binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
- <binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
<binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
</third_person>
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index 482012cdd6..2a26cb9a43 100644
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -73,6 +73,7 @@
<string>Avatar</string>
<string>Voice</string>
-->
+ <string>Capabilities</string>
</array>
</map>
</array>
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
deleted file mode 100644
index b31a040d67..0000000000
--- a/indra/newview/app_settings/low_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="0.5"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.0"/>
- <!--Short Range-->
- <RenderFarClip value="64"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="0.5"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="8"/>
- <!--Low number-->
- <RenderMaxPartCount value="1024"/>
- <!--bump okay-->
- <RenderObjectBump value="FALSE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="0"/>
- <!--Simple-->
- <RenderTerrainDetail value="0"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="12"/>
- <RenderAvatarMaxComplexity value="80000"/>
- <RenderAutoMuteSurfaceAreaLimit value="750.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="FALSE"/>
- <!--No Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--No Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
deleted file mode 100644
index 9c2c17fc60..0000000000
--- a/indra/newview/app_settings/mid_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="0.5"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.75"/>
- <!--Short Range-->
- <RenderFarClip value="96"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="8"/>
- <!--Low number-->
- <RenderMaxPartCount value="2048"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="0"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="18"/>
- <RenderAvatarMaxComplexity value="150000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1000.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="FALSE"/>
- <!--No Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--No Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index bc4945eca5..3f9a91e38f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -544,17 +544,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AvalinePhoneSeparator</key>
- <map>
- <key>Comment</key>
- <string>Separator of phone parts to have Avaline numbers human readable in Voice Control Panel</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>-</string>
- </map>
<key>AvatarAxisDeadZone0</key>
<map>
<key>Comment</key>
@@ -1252,6 +1241,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>BulkChangeIncludeMaterials</key>
+ <map>
+ <key>Comment</key>
+ <string>Bulk permission changes affect materials</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>BulkChangeEveryoneCopy</key>
<map>
<key>Comment</key>
@@ -1371,7 +1371,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>20.0</real>
+ <real>40.0</real>
</map>
<key>DiskCacheDirName</key>
<map>
@@ -3847,7 +3847,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>http://events.secondlife.com/viewer/embed/event/</string>
+ <string>http://events.[GRID]/viewer/embed/event/[EVENT_ID]</string>
</map>
<key>FastCacheFetchEnabled</key>
<map>
@@ -4758,7 +4758,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
+ <string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>GuidebookURL</key>
<map>
@@ -5806,6 +5806,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DiskCacheVersion</key>
+ <map>
+ <key>Comment</key>
+ <string>Version number of disk cache</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>LocalFileSystemBrowsingEnabled</key>
<map>
<key>Comment</key>
@@ -6808,6 +6819,9 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
+ <!-- *HACK: On first run, set this to 0 for new users,
+ otherwise the default is 1 to maintain consistent experience
+ for existing users. Hardcoded in llnetmap.cpp -->
<integer>1</integer>
</map>
<key>MiniMapScale</key>
@@ -6821,6 +6835,17 @@
<key>Value</key>
<real>128.0</real>
</map>
+ <key>MiniMapShowPropertyLines</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to show parcel borders on the MiniMap.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
<key>MouseSensitivity</key>
<map>
<key>Comment</key>
@@ -7099,13 +7124,13 @@
<key>NonvisibleObjectsInMemoryTime</key>
<map>
<key>Comment</key>
- <string>Number of frames non-visible objects stay in memory before being removed. 0 means never to remove.</string>
+ <string>Number of frames non-visible objects stay in memory before being removed. 0 means max.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>300</integer>
+ <integer>64</integer>
</map>
<key>NoPreload</key>
<map>
@@ -8635,6 +8660,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>UpdateRememberPasswordSetting</key>
+ <map>
+ <key>Comment</key>
+ <string>Save 'rememeber password' setting for current user.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>OctreeMaxNodeCapacity</key>
<map>
<key>Comment</key>
@@ -8784,13 +8820,13 @@
<key>RenderAvatarCloth</key>
<map>
<key>Comment</key>
- <string>Controls if avatars use wavy cloth</string>
+ <string>DEPRECATED - only false supported - Controls if avatars use wavy cloth</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>RenderComplexityColorMin</key>
<map>
@@ -9141,10 +9177,10 @@
<key>Value</key>
<real>0.5</real>
</map>
- <key>RenderDebugGL</key>
+ <key>RenderDebugGLSession</key>
<map>
<key>Comment</key>
- <string>Enable strict GL debugging.</string>
+ <string>Enable strict GL debugging on the start of next session.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9599,16 +9635,28 @@
<real>368.0</real>
</map>
+ <key>RenderPBR</key>
+ <map>
+ <key>Comment</key>
+ <string>DEPRECATED - only true supported - Use PBR rendering pipeline (Physically Based Rendering).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+
<key>RenderDeferred</key>
<map>
<key>Comment</key>
- <string>Use deferred rendering pipeline (Advanced Lighting Model).</string>
+ <string>DEPRECATED (only true supported) - Use deferred rendering pipeline (Advanced Lighting Model).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderDeferredSun</key>
@@ -9823,7 +9871,7 @@
<key>RenderFogRatio</key>
<map>
<key>Comment</key>
- <string>Distance from camera where fog reaches maximum density (fraction or multiple of far clip distance)</string>
+ <string>DEPRECATED - Distance from camera where fog reaches maximum density (fraction or multiple of far clip distance)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9834,7 +9882,7 @@
<key>RenderGamma</key>
<map>
<key>Comment</key>
- <string>Sets gamma exponent for renderer</string>
+ <string>DEPRECATED - Sets gamma exponent for renderer</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9867,7 +9915,7 @@
<key>RenderGLContextCoreProfile</key>
<map>
<key>Comment</key>
- <string>Don't use a compatibility profile OpenGL context. Requires restart. Basic shaders MUST be enabled.</string>
+ <string>Don't use a compatibility profile OpenGL context. Requires restart.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10227,7 +10275,7 @@
<key>RenderObjectBump</key>
<map>
<key>Comment</key>
- <string>Show bumpmapping on primitives</string>
+ <string>DEPRECATED (only TRUE supported) Show bumpmapping on primitives</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10249,7 +10297,7 @@
<key>RenderReflectionDetail</key>
<map>
<key>Comment</key>
- <string>Detail of reflection render pass.</string>
+ <string>DEPRECATED -- use RenderTransparentWater and RenderReflectionProbeDetail -- Detail of reflection render pass.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10268,8 +10316,64 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>RenderReflectionProbeDetail</key>
+ <map>
+ <key>Comment</key>
+ <string>Detail of reflections. (-1 - Disabled, 0 - Static Only, 1 - Static + Dynamic, 2 - Realtime)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>RenderReflectionProbeCount</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of reflection probes (maximum is 256, requires restart)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>256</integer>
+ </map>
- <key>RenderReflectionRes</key>
+ <key>RenderReflectionProbeDrawDistance</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera far clip to use when updating reflection probes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>64</real>
+ </map>
+ <key>RenderReflectionProbeAmbiance</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount reflection probes contribute to ambient light.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
+ <key>RenderReflectionProbeTextureHackID</key>
+ <map>
+ <key>Comment</key>
+ <string>HACK -- Any object with a diffuse texture with this ID will be treated as a user override reflection probe. (default is "Violet Info Hub" photo from Library)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>6b186931-05da-eafa-a3ed-a012a33bbfb6</string>
+ </map>
+
+ <key>RenderReflectionRes</key>
<map>
<key>Comment</key>
<string>Reflection map resolution.</string>
@@ -10660,18 +10764,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderUseTransformFeedback</key>
- <map>
- <key>Comment</key>
- <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
-
<key>RenderVBOMappingDisable</key>
<map>
<key>Comment</key>
@@ -11000,7 +11092,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>1024</integer>
+ <integer>2048</integer>
</map>
<key>SceneLoadLowMemoryBound</key>
<map>
@@ -11134,6 +11226,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>SelectInvisibleObjects</key>
+ <map>
+ <key>Comment</key>
+ <string>Select invisible objects</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>SelectOwnedOnly</key>
<map>
<key>Comment</key>
@@ -14735,7 +14838,7 @@
<key>WindLightUseAtmosShaders</key>
<map>
<key>Comment</key>
- <string>Whether to enable or disable WindLight atmospheric shaders.</string>
+ <string>DEPRECATED (only true supported) - Whether to enable or disable WindLight atmospheric shaders.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -15607,6 +15710,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>AllowSelectAvatar</key>
+ <map>
+ <key>Comment</key>
+ <string>Allows user to select and move avatars, move is viewer sided, does not propagate to server, also supresses avatar position updates while avatars are selected</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>WebProfileFloaterRect</key>
<map>
<key>Comment</key>
@@ -16013,6 +16127,61 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>MaterialsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>MaterialsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>MaterialsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>MaterialsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created GLTF material</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>MaterialsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF materials are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DefaultUploadPermissionsConverted</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 537744b44c..eb3528b9b7 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -370,6 +370,17 @@
<key>Value</key>
<string></string>
</map>
+ <key>PBRUploadFolder</key>
+ <map>
+ <key>Comment</key>
+ <string>All pbr uploads will be stored in this directory (UUID)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string></string>
+ </map>
<key>TextureUploadFolder</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 02b2daf0ac..f4ec1ec532 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -25,305 +25,11 @@
//class1/deferred/alphaF.glsl
-#extension GL_ARB_texture_rectangle : enable
-/*[EXTRA_CODE_HERE]*/
-
-#define INDEXED 1
-#define NON_INDEXED 2
-#define NON_INDEXED_NO_COLOR 3
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform mat3 env_mat;
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-
-#ifdef USE_DIFFUSE_TEX
-uniform sampler2D diffuseMap;
-#endif
-
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_norm;
-
-#ifdef USE_VERTEX_COLOR
-VARYING vec4 vertex_color; //vertex color should be treated as sRGB
-#endif
-
-#ifdef HAS_ALPHA_MASK
-uniform float minimum_alpha;
-#endif
-
-uniform mat4 proj_mat;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-uniform int sun_up_factor;
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec4 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
-
-vec3 srgb_to_linear(vec3 c);
-vec3 linear_to_srgb(vec3 c);
-
-vec2 encode_normal (vec3 n);
-vec3 scaleSoftClipFrag(vec3 l);
-vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive, bool use_ao);
-
-#ifdef HAS_SHADOW
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-#endif
-
-float getAmbientClamp();
-
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
-{
- // SL-14895 inverted attenuation work-around
- // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
- // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
- // to recover the `adjusted_radius` value previously being sent as la.
- float falloff_factor = (12.0 * fa) - 9.0;
- float inverted_la = falloff_factor / la;
- // Yes, it makes me want to cry as well. DJH
-
- vec3 col = vec3(0);
-
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float dist = length(lv);
- float da = 1.0;
- /*if (dist > inverted_la)
- {
- return col;
- }
-
- clip to projector bounds
- vec4 proj_tc = proj_mat * lp;
-
- if (proj_tc.z < 0
- || proj_tc.z > 1
- || proj_tc.x < 0
- || proj_tc.x > 1
- || proj_tc.y < 0
- || proj_tc.y > 1)
- {
- return col;
- }*/
-
- if (dist > 0.0 && inverted_la > 0.0)
- {
- dist /= inverted_la;
-
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0f;
-
- if (dist_atten <= 0.0)
- {
- return col;
- }
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= dot(n, lv);
- da = max(0.0, da);
-
- float lit = 0.0f;
-
- float amb_da = 0.0;//ambiance;
- if (da > 0)
- {
- lit = max(da * dist_atten,0.0);
- col = lit * light_col * diffuse;
- amb_da += (da*0.5+0.5) * ambiance;
- }
- amb_da += (da*da*0.5 + 0.5) * ambiance;
- amb_da *= dist_atten;
- amb_da = min(amb_da, 1.0f - lit);
-
- // SL-10969 ... need to work out why this blows out in many setups...
- //col.rgb += amb_da * light_col * diffuse;
-
- // no spec for alpha shader...
- }
- col = max(col, vec3(0));
- return col;
-}
-
-void main()
+void main()
{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- vec4 pos = vec4(vary_position, 1.0);
- vec3 norm = vary_norm;
-
- float shadow = 1.0f;
-
-#ifdef HAS_SHADOW
- shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
-#endif
-
-#ifdef USE_DIFFUSE_TEX
- vec4 diffuse_tap = texture2D(diffuseMap,vary_texcoord0.xy);
-#endif
-
-#ifdef USE_INDEXED_TEX
- vec4 diffuse_tap = diffuseLookup(vary_texcoord0.xy);
-#endif
-
- vec4 diffuse_srgb = diffuse_tap;
-
-#ifdef FOR_IMPOSTOR
- vec4 color;
- color.rgb = diffuse_srgb.rgb;
- color.a = 1.0;
-
- float final_alpha = diffuse_srgb.a * vertex_color.a;
- diffuse_srgb.rgb *= vertex_color.rgb;
-
- // Insure we don't pollute depth with invis pixels in impostor rendering
- //
- if (final_alpha < minimum_alpha)
- {
- discard;
- }
-
- color.rgb = diffuse_srgb.rgb;
- color.a = final_alpha;
-
-#else // FOR_IMPOSTOR
-
- vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
-
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir;
-
- float final_alpha = diffuse_linear.a;
-
-#ifdef USE_VERTEX_COLOR
- final_alpha *= vertex_color.a;
-
- if (final_alpha < minimum_alpha)
- { // TODO: figure out how to get invisible faces out of
- // render batches without breaking glow
- discard;
- }
-
- diffuse_srgb.rgb *= vertex_color.rgb;
- diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
-#endif // USE_VERTEX_COLOR
-
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
-
- calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
-
- vec2 abnormal = encode_normal(norm.xyz);
-
- float da = dot(norm.xyz, light_dir.xyz);
- da = clamp(da, -1.0, 1.0);
- da = pow(da, 1.0/1.3);
-
- float final_da = da;
- final_da = clamp(final_da, 0.0f, 1.0f);
-
- vec4 color = vec4(0.0);
-
- color.a = final_alpha;
-
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
-
- vec3 sun_contrib = min(final_da, shadow) * sunlit;
-
-#if !defined(AMBIENT_KILL)
- color.rgb = amblit;
- color.rgb *= ambient;
-#endif // !defined(AMBIENT_KILL)
-
-vec3 post_ambient = color.rgb;
-
-#if !defined(SUNLIGHT_KILL)
- color.rgb += sun_contrib;
-#endif // !defined(SUNLIGHT_KILL)
-
-vec3 post_sunlight = color.rgb;
-
- color.rgb *= diffuse_srgb.rgb;
-
-vec3 post_diffuse = color.rgb;
-
- color.rgb = atmosFragLighting(color.rgb, additive, atten);
-
-vec3 post_atmo = color.rgb;
-
- vec4 light = vec4(0,0,0,0);
-
- color.rgb = scaleSoftClipFrag(color.rgb);
-
- //convert to linear before applying local lights
- color.rgb = srgb_to_linear(color.rgb);
-
- #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
-
- LIGHT_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
-
- // sum local light contrib in linear colorspace
-#if !defined(LOCAL_LIGHT_KILL)
- color.rgb += light.rgb;
-#endif // !defined(LOCAL_LIGHT_KILL)
- // back to sRGB as we're going directly to the final RT post-deferred gamma correction
- color.rgb = linear_to_srgb(color.rgb);
-
-//color.rgb = amblit;
-//color.rgb = vec3(ambient);
-//color.rgb = sunlit;
-//color.rgb = vec3(final_da);
-//color.rgb = post_ambient;
-//color.rgb = post_sunlight;
-//color.rgb = sun_contrib;
-//color.rgb = diffuse_srgb.rgb;
-//color.rgb = post_diffuse;
-//color.rgb = post_atmo;
-
-#ifdef WATER_FOG
- color = applyWaterFogView(pos.xyz, color);
-#endif // WATER_FOG
-
-#endif // #else // FOR_IMPOSTOR
-
- frag_color = color;
+ frag_color = vec4(1,0,1,0.5);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
index c64b6ba240..c2372fcbc0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
@@ -58,7 +58,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
index b54c580ce9..d0a049d372 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
@@ -35,7 +35,7 @@ uniform sampler2D diffuseMap;
VARYING float pos_w;
VARYING float target_pos_x;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -61,7 +61,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
index 31b93dc36a..a7bf4d7780 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
@@ -1,5 +1,5 @@
/**
- * @file attachmentShadowV.glsl
+ * @file attachmentAlphaShadowV.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
@@ -35,7 +35,7 @@ ATTRIBUTE vec2 texcoord0;
mat4 getObjectSkinnedTransform();
void passTextureIndex();
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING vec2 vary_texcoord0;
@@ -61,7 +61,7 @@ void main()
vertex_color = diffuse_color;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
p.z = max(p.z, -p.w+0.01);
post_pos = p;
gl_Position = p;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
index b8ce54bcb1..f231213ac8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
@@ -1,5 +1,5 @@
/**
- * @file treeShadowF.glsl
+ * @file avatarAlphaMaskShadowF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,7 +32,7 @@ out vec4 frag_color;
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -59,7 +59,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
index 1b16e4eb09..0e66c722b6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
@@ -33,7 +33,7 @@ uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -61,7 +61,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
index 1c5b142ebd..40ac7b1f95 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
@@ -1,5 +1,5 @@
/**
- * @file avatarShadowV.glsl
+ * @file avatarAlphaShadowV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -34,7 +34,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING float pos_w;
@@ -66,7 +66,7 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 60d83cc623..22b3bd1463 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -52,6 +52,6 @@ void main()
frag_data[0] = vec4(diff.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index 596d0274af..fa3634f3b6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -69,36 +69,47 @@ void main()
tc_mod *= 2.0;
tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
- for (int i = 1; i < 4; i++)
+ // TODO: move this to kern instead of building kernel per pixel
+ vec3 k[7];
+ k[0] = kern[0];
+ k[2] = kern[1];
+ k[4] = kern[2];
+ k[6] = kern[3];
+
+ k[1] = (k[0]+k[2])*0.5f;
+ k[3] = (k[2]+k[4])*0.5f;
+ k[5] = (k[4]+k[6])*0.5f;
+
+ for (int i = 1; i < 7; i++)
{
- vec2 samptc = tc + kern[i].z*dlt;
+ vec2 samptc = tc + k[i].z*dlt*2.0;
vec3 samppos = getPosition(samptc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= pointplanedist_tolerance_pow2)
{
- col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
- defined_weight += kern[i].xy;
+ col += texture2DRect(lightMap, samptc)*k[i].xyxx;
+ defined_weight += k[i].xy;
}
}
- for (int i = 1; i < 4; i++)
+ for (int i = 1; i < 7; i++)
{
- vec2 samptc = tc - kern[i].z*dlt;
+ vec2 samptc = tc - k[i].z*dlt*2.0;
vec3 samppos = getPosition(samptc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= pointplanedist_tolerance_pow2)
{
- col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
- defined_weight += kern[i].xy;
+ col += texture2DRect(lightMap, samptc)*k[i].xyxx;
+ defined_weight += k[i].xy;
}
}
col /= defined_weight.xyxx;
- col.y *= col.y;
+ //col.y *= max(col.y, 0.75);
frag_color = col;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index b5677a07ee..749ec3a6ac 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -64,5 +64,5 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(tnorm);
- frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
deleted file mode 100644
index 0157d166e0..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 sunlight_color;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-void main()
-{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- if (cloud_scale >= 0.0001)
- {
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = vec4(alpha1, alpha1, alpha1, 1);
- }
- else
- {
- frag_color = vec4(1);
- }
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
deleted file mode 100644
index effb070f93..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index ae1ac5de7f..788ce4a47b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -34,15 +34,15 @@ out vec4 frag_data[3];
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec3 vary_CloudColorSun;
+VARYING vec3 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
uniform sampler2D cloud_noise_texture;
uniform sampler2D cloud_noise_texture_next;
uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
+uniform vec3 cloud_pos_density1;
+uniform vec3 cloud_pos_density2;
uniform float cloud_scale;
uniform float cloud_variance;
@@ -69,8 +69,8 @@ void main()
vec2 uv1 = vary_texcoord0.xy;
vec2 uv2 = vary_texcoord1.xy;
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ vec3 cloudColorSun = vary_CloudColorSun;
+ vec3 cloudColorAmbient = vary_CloudColorAmbient;
float cloudDensity = vary_CloudDensity;
vec2 uv3 = vary_texcoord2.xy;
vec2 uv4 = vary_texcoord3.xy;
@@ -115,7 +115,7 @@ void main()
alpha2 = 1. - alpha2 * alpha2;
// Combine
- vec4 color;
+ vec3 color;
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
color.rgb= max(vec3(0), color.rgb);
color.rgb *= 2.0;
@@ -124,7 +124,7 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, alpha1);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0,0,0,1);
+ frag_data[2] = vec4(0,0,0,GBUFFER_FLAG_SKIP_ATMOS);
gl_FragDepth = 0.99995f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index 8e0a001403..5ca210863e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -33,8 +33,8 @@ ATTRIBUTE vec2 texcoord0;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec3 vary_CloudColorSun;
+VARYING vec3 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
VARYING vec2 vary_texcoord0;
@@ -46,13 +46,13 @@ VARYING float altitude_blend_factor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -60,10 +60,10 @@ uniform float cloud_shadow;
uniform float density_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
+uniform vec3 cloud_color;
uniform float cloud_scale;
@@ -114,17 +114,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
+ vec3 sunlight = sunlight_color;
+ vec3 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);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -155,14 +155,14 @@ void main()
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
+ vec3 tmpAmbient = ambient_color;
tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= (1. - cloud_shadow);
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// CLOUDS
@@ -178,7 +178,7 @@ void main()
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
vary_CloudColorSun *= combined_haze;
vary_CloudColorAmbient *= combined_haze;
- vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
+ vec3 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
// Make a nice cloud density based on the cloud_shadow value that was passed in.
vary_CloudDensity = 2. * (cloud_shadow - 0.25);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index e27bbce094..1a96ee0736 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -23,12 +23,118 @@
* $/LicenseInfo$
*/
+
+/* Parts of this file are taken from Sascha Willem's Vulkan GLTF refernce implementation
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
uniform sampler2DRect normalMap;
uniform sampler2DRect depthMap;
+uniform sampler2D projectionMap; // rgba
+uniform sampler2D brdfLut;
+
+// projected lighted params
+uniform mat4 proj_mat; //screen space to light space projector
+uniform vec3 proj_n; // projector normal
+uniform vec3 proj_p; //plane projection is emitting from (in screen space)
+uniform float proj_focus; // distance from plane to begin blurring
+uniform float proj_lod ; // (number of mips in proj map)
+uniform float proj_range; // range between near clip and far clip plane of projection
+uniform float proj_ambiance;
+
+// light params
+uniform vec3 color; // light_color
+uniform float size; // light_size
uniform mat4 inv_proj;
uniform vec2 screen_res;
+const float M_PI = 3.14159265;
+const float ONE_OVER_PI = 0.3183098861;
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFragLinear(vec3 light);
+
+float calcLegacyDistanceAttenuation(float distance, float falloff)
+{
+ float dist_atten = 1.0 - clamp((distance + falloff)/(1.0 + falloff), 0.0, 1.0);
+ dist_atten *= dist_atten;
+
+ // Tweak falloff slightly to match pre-EEP attenuation
+ // NOTE: this magic number also shows up in a great many other places, search for dist_atten *= to audit
+ dist_atten *= 2.0;
+ return dist_atten;
+}
+
+// In:
+// lv unnormalized surface to light vector
+// n normal of the surface
+// pos unnormalized camera to surface vector
+// Out:
+// l normalized surace to light vector
+// nl diffuse angle
+// nh specular angle
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v,
+ out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist)
+{
+ l = normalize(lv);
+ h = normalize(l + v);
+ nh = clamp(dot(n, h), 0.0, 1.0);
+ nl = clamp(dot(n, l), 0.0, 1.0);
+ nv = clamp(dot(n, v), 0.0, 1.0);
+ vh = clamp(dot(v, h), 0.0, 1.0);
+
+ lightDist = length(lv);
+}
+
+// In:
+// light_center
+// pos
+// Out:
+// dist
+// l_dist
+// lv
+// proj_tc Projector Textue Coordinates
+bool clipProjectedLightVars(vec3 light_center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc )
+{
+ lv = light_center - pos.xyz;
+ dist = length(lv);
+ bool clipped = (dist >= size);
+ if ( !clipped )
+ {
+ dist /= size;
+
+ l_dist = -dot(lv, proj_n);
+ vec4 projected_point = (proj_mat * vec4(pos.xyz, 1.0));
+ clipped = (projected_point.z < 0.0);
+ projected_point.xyz /= projected_point.w;
+ proj_tc = projected_point;
+ }
+
+ return clipped;
+}
+
vec2 getScreenCoordinate(vec2 screenpos)
{
vec2 sc = screenpos.xy * 2.0;
@@ -39,6 +145,8 @@ vec2 getScreenCoordinate(vec2 screenpos)
return sc - vec2(1.0, 1.0);
}
+// See: https://aras-p.info/texts/CompactNormalStorage.html
+// Method #4: Spheremap Transform, Lambert Azimuthal Equal-Area projection
vec3 getNorm(vec2 screenpos)
{
vec2 enc = texture2DRect(normalMap, screenpos.xy).xy;
@@ -51,12 +159,155 @@ vec3 getNorm(vec2 screenpos)
return n;
}
+vec3 getNormalFromPacked(vec4 packedNormalEnvIntensityFlags)
+{
+ vec2 enc = packedNormalEnvIntensityFlags.xy;
+ 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 normalize(n); // TODO: Is this normalize redundant?
+}
+
+// return packedNormalEnvIntensityFlags since GBUFFER_FLAG_HAS_PBR needs .w
+// See: C++: addDeferredAttachments(), GLSL: softenLightF
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity)
+{
+ vec4 packedNormalEnvIntensityFlags = texture2DRect(normalMap, screenpos.xy);
+ n = getNormalFromPacked( packedNormalEnvIntensityFlags );
+ envIntensity = packedNormalEnvIntensityFlags.z;
+ return packedNormalEnvIntensityFlags;
+}
+
+// get linear depth value given a depth buffer sample d and znear and zfar values
+float linearDepth(float d, float znear, float zfar)
+{
+ d = d * 2.0 - 1.0;
+ return znear * 2.0 * zfar / (zfar + znear - d * (zfar - znear));
+}
+
float getDepth(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen).r;
return depth;
}
+vec4 getTexture2DLodAmbient(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture2D(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = tc-vec2(0.5);
+ float d = dot(dist,dist);
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+vec4 getTexture2DLodDiffuse(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture2D(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+ float det = min(lod/(proj_lod*0.5), 1.0);
+ float d = min(dist.x, dist.y);
+ float edge = 0.25*det;
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+// lit This is set by the caller: if (nl > 0.0) { lit = attenuation * nl * noise; }
+// Uses:
+// color Projected spotlight color
+vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv)
+{
+ vec4 amb_plcol = getTexture2DLodAmbient(projected_uv, proj_lod);
+ vec3 amb_rgb = amb_plcol.rgb * amb_plcol.a;
+
+ amb_da += proj_ambiance;
+ amb_da += (nl*nl*0.5+0.5) * proj_ambiance;
+ amb_da *= attenuation * noise;
+ amb_da = min(amb_da, 1.0-lit);
+
+ return (amb_da * color.rgb * amb_rgb);
+}
+
+// Returns projected light in Linear
+// Uses global spotlight color:
+// color
+// NOTE: projected.a will be pre-multiplied with projected.rgb
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv)
+{
+ float diff = clamp((light_distance - proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+ vec4 plcol = getTexture2DLodDiffuse(projected_uv.xy, lod);
+
+ return color.rgb * plcol.rgb * plcol.a;
+}
+
+vec4 texture2DLodSpecular(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture2D(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+ float det = min(lod/(proj_lod*0.5), 1.0);
+ float d = min(dist.x, dist.y);
+ d *= min(1, d * (proj_lod - lod)); // BUG? extra factor compared to diffuse causes N repeats
+ float edge = 0.25*det;
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+// See: clipProjectedLightVars()
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n )
+{
+ vec3 slit = vec3(0);
+ vec3 ref = reflect(normalize(pos), n);
+
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float l_dist = length(pdelta);
+ float ds = dot(ref, proj_n);
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ if (stc.z > 0.0)
+ {
+ stc /= stc.w;
+ slit = getProjectedLightDiffuseColor( l_dist, stc.xy ); // NOTE: Using diffuse due to texture2DLodSpecular() has extra: d *= min(1, d * (proj_lod - lod));
+ }
+ }
+ return slit; // specular light
+}
+
+vec3 getProjectedLightSpecularColor(float light_distance, vec2 projected_uv)
+{
+ float diff = clamp((light_distance - proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+ vec4 plcol = getTexture2DLodDiffuse(projected_uv.xy, lod); // NOTE: Using diffuse due to texture2DLodSpecular() has extra: d *= min(1, d * (proj_lod - lod));
+
+ return color.rgb * plcol.rgb * plcol.a;
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = getDepth(pos_screen);
@@ -68,12 +319,241 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+// get position given a normalized device coordinate
+vec3 getPositionWithNDC(vec3 ndc)
+{
+ vec4 pos = inv_proj * vec4(ndc, 1.0);
+ return pos.xyz / pos.w;
+}
+
vec4 getPositionWithDepth(vec2 pos_screen, float depth)
{
vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
+ vec3 ndc = vec3(sc.x, sc.y, 2.0*depth-1.0);
+ return vec4(getPositionWithNDC(ndc), 1.0);
+}
+
+
+vec2 getScreenXY(vec4 clip)
+{
+ vec4 ndc = clip;
+ ndc.xyz /= clip.w;
+ vec2 screen = vec2( ndc.xy * 0.5 );
+ screen += 0.5;
+ screen *= screen_res;
+ return screen;
+}
+
+// Color utils
+
+vec3 colorize_dot(float x)
+{
+ if (x > 0.0) return vec3( 0, x, 0 );
+ if (x < 0.0) return vec3(-x, 0, 0 );
+ return vec3( 0, 0, 1 );
+}
+
+vec3 hue_to_rgb(float hue)
+{
+ if (hue > 1.0) return vec3(0.5);
+ vec3 rgb = abs(hue * 6. - vec3(3, 2, 4)) * vec3(1, -1, -1) + vec3(-1, 2, 2);
+ return clamp(rgb, 0.0, 1.0);
}
+
+// PBR Utils
+
+vec2 BRDF(float NoV, float roughness)
+{
+ return texture(brdfLut, vec2(NoV, roughness)).rg;
+}
+
+// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRough)
+{
+ // retrieve a scale and bias to F0. See [1], Figure 3
+ vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
+ vec3 diffuseLight = irradiance;
+ vec3 specularLight = radiance;
+
+ vec3 diffuse = diffuseLight * diffuseColor;
+ vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
+
+ return (diffuse + specular*0.5) * ao; //reduce by half to place in appropriate color space for atmospherics
+}
+
+// Encapsulate the various inputs used by the various functions in the shading equation
+// We store values in this struct to simplify the integration of alternative implementations
+// of the shading terms, outlined in the Readme.MD Appendix.
+struct PBRInfo
+{
+ float NdotL; // cos angle between normal and light direction
+ float NdotV; // cos angle between normal and view direction
+ float NdotH; // cos angle between normal and half vector
+ float LdotH; // cos angle between light direction and half vector
+ float VdotH; // cos angle between view direction and half vector
+ float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
+ float metalness; // metallic value at the surface
+ vec3 reflectance0; // full reflectance color (normal incidence angle)
+ vec3 reflectance90; // reflectance color at grazing angle
+ float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
+ vec3 diffuseColor; // color contribution from diffuse lighting
+ vec3 specularColor; // color contribution from specular lighting
+};
+
+// Basic Lambertian diffuse
+// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
+// See also [1], Equation 1
+vec3 diffuse(PBRInfo pbrInputs)
+{
+ return pbrInputs.diffuseColor / M_PI;
+}
+
+// The following equation models the Fresnel reflectance term of the spec equation (aka F())
+// Implementation of fresnel from [4], Equation 15
+vec3 specularReflection(PBRInfo pbrInputs)
+{
+ return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
+}
+
+// This calculates the specular geometric attenuation (aka G()),
+// where rougher material will reflect less light back to the viewer.
+// This implementation is based on [1] Equation 4, and we adopt their modifications to
+// alphaRoughness as input as originally proposed in [2].
+float geometricOcclusion(PBRInfo pbrInputs)
+{
+ float NdotL = pbrInputs.NdotL;
+ float NdotV = pbrInputs.NdotV;
+ float r = pbrInputs.alphaRoughness;
+
+ float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
+ float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
+ return attenuationL * attenuationV;
+}
+
+// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D())
+// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
+// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3.
+float microfacetDistribution(PBRInfo pbrInputs)
+{
+ float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
+ float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
+ return roughnessSq / (M_PI * f * f);
+}
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l) //surface point to light
+{
+ // make sure specular highlights from punctual lights don't fall off of polished surfaces
+ perceptualRoughness = max(perceptualRoughness, 8.0/255.0);
+
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
+
+ // Compute reflectance.
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
+
+ // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
+ // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
+ vec3 specularEnvironmentR0 = specularColor.rgb;
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
+
+ vec3 h = normalize(l+v); // Half vector between both l and v
+ vec3 reflection = -normalize(reflect(v, n));
+ reflection.y *= -1.0f;
+
+ float NdotL = clamp(dot(n, l), 0.001, 1.0);
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
+ float NdotH = clamp(dot(n, h), 0.0, 1.0);
+ float LdotH = clamp(dot(l, h), 0.0, 1.0);
+ float VdotH = clamp(dot(v, h), 0.0, 1.0);
+
+ PBRInfo pbrInputs = PBRInfo(
+ NdotL,
+ NdotV,
+ NdotH,
+ LdotH,
+ VdotH,
+ perceptualRoughness,
+ metallic,
+ specularEnvironmentR0,
+ specularEnvironmentR90,
+ alphaRoughness,
+ diffuseColor,
+ specularColor
+ );
+
+ // Calculate the shading terms for the microfacet specular shading model
+ vec3 F = specularReflection(pbrInputs);
+ float G = geometricOcclusion(pbrInputs);
+ float D = microfacetDistribution(pbrInputs);
+
+ const vec3 u_LightColor = vec3(1.0);
+
+ // Calculation of analytical lighting contribution
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
+ vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
+ vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
+
+ return color;
+}
+
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor)
+{
+ vec3 f0 = vec3(0.04);
+ diffuseColor = baseColor*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+ specularColor = mix(f0, baseColor, metallic);
+}
+
+vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten)
+{
+ vec3 color = vec3(0);
+
+ float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
+
+ color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness);
+
+ color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir)) * sunlit * 2.75 * scol;
+ color += colorEmissive*0.5;
+
+ color = atmosFragLightingLinear(color, additive, atten);
+ color = scaleSoftClipFragLinear(color);
+
+ return color;
+}
+
+uniform vec4 waterPlane;
+uniform float waterSign;
+
+// discard if given position in eye space is on the wrong side of the waterPlane according to waterSign
+void waterClip(vec3 pos)
+{
+ // TODO: make this less branchy
+ if (waterSign > 0)
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < -0.1)
+ {
+ discard;
+ }
+ }
+ else
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > -0.1)
+ {
+ discard;
+ }
+ }
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index b328ee9483..3bf148502c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -53,6 +53,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index fc5c86b4d6..e15239b59d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -52,5 +52,5 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
index 1bb8eb8bd0..b0ff233414 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -52,6 +52,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 8319e61242..b2d2e2fa71 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -46,6 +46,6 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index ccd1df84f9..b4bc114dd5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -48,5 +48,5 @@ void main()
frag_data[0] = vec4(col, 0.0);
frag_data[1] = vec4(spec, vertex_color.a); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 57420158ca..33b97aefcb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -82,7 +82,7 @@ void main()
color.a = final_alpha;
#endif
- frag_color.rgb = color.rgb;
+ frag_color.rgb = srgb_to_linear(color.rgb);
frag_color.a = color.a;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
index 9fcee04c32..f693323d45 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -38,7 +38,7 @@ uniform sampler2D diffuseMap;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-VARYING vec4 vary_position;
+VARYING vec3 vary_position;
uniform samplerCube environmentMap;
@@ -74,7 +74,7 @@ void main()
vec3 amblit;
vec3 additive;
vec3 atten;
- vec3 pos = vary_position.xyz/vary_position.w;
+ vec3 pos = vary_position.xyz;
calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
index 3bd6b693fa..0e461b4004 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
@@ -45,7 +45,7 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-VARYING vec4 vary_position;
+VARYING vec3 vary_position;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
@@ -62,17 +62,18 @@ void main()
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec4 pos = mat * vert;
- vary_position = gl_Position = projection_matrix * pos;
+ gl_Position = projection_matrix * pos;
vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
#else
vec4 pos = (modelview_matrix * vert);
- vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vec3 norm = normalize(normal_matrix * normal);
#endif
- vec3 ref = reflect(pos.xyz, -norm);
+ vary_position = pos.xyz;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz;
+
+ vary_texcoord1 = norm;
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
new file mode 100644
index 0000000000..9e6c853015
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
@@ -0,0 +1,141 @@
+/**
+ * @file class1/deferred/genbrdflut.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+/* Taken from Sascha Willem's Vulkan GLTF refernce implementation
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+VARYING vec2 vary_uv;
+
+out vec4 outColor;
+
+#define NUM_SAMPLES 1024u
+
+const float PI = 3.1415926536;
+
+// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+float random(vec2 co)
+{
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
+}
+
+vec2 hammersley2d(uint i, uint N)
+{
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
+}
+
+// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+{
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+}
+
+// Geometric Shadowing function
+float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
+{
+ float k = (roughness * roughness) / 2.0;
+ float GL = dotNL / (dotNL * (1.0 - k) + k);
+ float GV = dotNV / (dotNV * (1.0 - k) + k);
+ return GL * GV;
+}
+
+vec2 BRDF(float NoV, float roughness)
+{
+ // Normal always points along z-axis for the 2D lookup
+ const vec3 N = vec3(0.0, 0.0, 1.0);
+ vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV);
+
+ vec2 LUT = vec2(0.0);
+ for(uint i = 0u; i < NUM_SAMPLES; i++) {
+ vec2 Xi = hammersley2d(i, NUM_SAMPLES);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+
+ float dotNL = max(dot(N, L), 0.0);
+ float dotNV = max(dot(N, V), 0.0);
+ float dotVH = max(dot(V, H), 0.0);
+ float dotNH = max(dot(H, N), 0.0);
+
+ if (dotNL > 0.0) {
+ float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
+ float G_Vis = (G * dotVH) / (dotNH * dotNV);
+ float Fc = pow(1.0 - dotVH, 5.0);
+ LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis);
+ }
+ }
+ return LUT / float(NUM_SAMPLES);
+}
+
+void main()
+{
+ outColor = vec4(BRDF(vary_uv.s, 1.0-vary_uv.t), 0.0, 1.0);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl
index bc5eb5181d..682244478b 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl
@@ -1,9 +1,9 @@
/**
- * @file sunLightV.glsl
+ * @file class3\deferred\genbrdflutV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -27,15 +27,13 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
-VARYING vec2 vary_fragcoord;
-
-uniform vec2 screen_res;
+VARYING vec2 vary_uv;
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
-
- vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;
+ vary_uv = position.xy*0.5+0.5;
+
+ gl_Position = vec4(position.xyz, 1.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
index 90566393d2..75f914cb02 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
@@ -38,5 +38,5 @@ void main()
{
frag_data[0] = color*texture2D(diffuseMap, vary_texcoord0.xy);
frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index a58cc3d12d..51afda2791 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -41,6 +41,7 @@ uniform sampler2D specularMap;
VARYING vec2 vary_texcoord0;
vec3 linear_to_srgb(vec3 c);
+vec2 encode_normal (vec3 n);
void main()
{
@@ -56,5 +57,5 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = spec;
- frag_data[2] = norm;
+ frag_data[2] = vec4(encode_normal(norm.xyz),0,GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 02d83925ea..51a36935f2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -23,431 +23,30 @@
* $/LicenseInfo$
*/
+
/*[EXTRA_CODE_HERE]*/
//class1/deferred/materialF.glsl
-// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
+// Debug stub for non-pbr material
-#define DIFFUSE_ALPHA_MODE_NONE 0
#define DIFFUSE_ALPHA_MODE_BLEND 1
-#define DIFFUSE_ALPHA_MODE_MASK 2
-#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
-
-uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 otherwise
-uniform int sun_up_factor;
-
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
-
-vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
-vec3 scaleSoftClipFrag(vec3 l);
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-vec3 srgb_to_linear(vec3 cs);
-vec3 linear_to_srgb(vec3 cs);
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
-#define frag_color gl_FragColor
-#endif
-
-#ifdef HAS_SUN_SHADOW
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+out vec4 frag_data[4];
#endif
-uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-uniform mat3 env_mat;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-VARYING vec2 vary_fragcoord;
-
-VARYING vec3 vary_position;
-
-uniform mat4 proj_mat;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec4 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float getAmbientClamp();
-
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
-{
- // SL-14895 inverted attenuation work-around
- // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
- // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
- // to recover the `adjusted_radius` value previously being sent as la.
- float falloff_factor = (12.0 * fa) - 9.0;
- float inverted_la = falloff_factor / la;
- // Yes, it makes me want to cry as well. DJH
-
- vec3 col = vec3(0);
-
- //get light vector
- vec3 lv = lp.xyz - v;
-
- //get distance
- float dist = length(lv);
- float da = 1.0;
-
- dist /= inverted_la;
-
- if (dist > 0.0 && inverted_la > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0f;
-
- if (dist_atten <= 0.0)
- {
- return col;
- }
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= dot(n, lv);
-
- float lit = 0.0f;
-
- float amb_da = ambiance;
- if (da >= 0)
- {
- lit = max(da * dist_atten, 0.0);
- col = lit * light_col * diffuse;
- amb_da += (da*0.5 + 0.5) * ambiance;
- }
- amb_da += (da*da*0.5 + 0.5) * ambiance;
- amb_da *= dist_atten;
- amb_da = min(amb_da, 1.0f - lit);
-
- // SL-10969 need to see why these are blown out
- //col.rgb += amb_da * light_col * diffuse;
-
- if (spec.a > 0.0)
- {
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv + npos);
- float nh = dot(n, h);
- float nv = dot(n, 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);
- vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
- speccol = clamp(speccol, vec3(0), vec3(1));
- col += speccol;
-
- float cur_glare = max(speccol.r, speccol.g);
- cur_glare = max(cur_glare, speccol.b);
- glare = max(glare, speccol.r);
- glare += max(cur_glare, 0.0);
- }
- }
- }
-
- return max(col, vec3(0.0, 0.0, 0.0));
-}
-
-#else
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-#endif
-
-uniform sampler2D diffuseMap; //always in sRGB space
-
-#ifdef HAS_NORMAL_MAP
-uniform sampler2D bumpMap;
-#endif
-
-#ifdef HAS_SPECULAR_MAP
-uniform sampler2D specularMap;
-
-VARYING vec2 vary_texcoord2;
-#endif
-
-uniform float env_intensity;
-uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-uniform float minimum_alpha;
-#endif
-
-#ifdef HAS_NORMAL_MAP
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
-VARYING vec2 vary_texcoord1;
-#else
-VARYING vec3 vary_normal;
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec2 encode_normal(vec3 n);
-
void main()
{
- vec2 pos_screen = vary_texcoord0.xy;
-
- vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
- diffcol.rgb *= vertex_color.rgb;
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-
- // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
- float bias = 0.001953125; // 1/512, or half an 8-bit quantization
- if (diffcol.a < minimum_alpha-bias)
- {
- discard;
- }
-#endif
-
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
- vec3 gamma_diff = diffcol.rgb;
- diffcol.rgb = srgb_to_linear(diffcol.rgb);
-#endif
-
-#ifdef HAS_SPECULAR_MAP
- vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
- spec.rgb *= specular_color.rgb;
+ frag_color = vec4(1, 0, 0, 0.5);
#else
- vec4 spec = vec4(specular_color.rgb, 1.0);
-#endif
-
-#ifdef HAS_NORMAL_MAP
- vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
-
- norm.xyz = norm.xyz * 2 - 1;
-
- vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
- dot(norm.xyz,vary_mat1),
- dot(norm.xyz,vary_mat2));
-#else
- vec4 norm = vec4(0,0,0,1.0);
- vec3 tnorm = vary_normal;
-#endif
-
- norm.xyz = normalize(tnorm.xyz);
-
- vec2 abnormal = encode_normal(norm.xyz);
-
- vec4 final_color = diffcol;
-
-#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
- final_color.a = emissive_brightness;
-#else
- final_color.a = max(final_color.a, emissive_brightness);
-#endif
-
- vec4 final_specular = spec;
-
-#ifdef HAS_SPECULAR_MAP
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
- final_specular.a = specular_color.a * norm.a;
-#else
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
- final_specular.a = specular_color.a;
-#endif
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
- //forward rendering, output just lit sRGBA
- vec3 pos = vary_position;
-
- float shadow = 1.0f;
-
-#ifdef HAS_SUN_SHADOW
- shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
-#endif
-
- spec = final_specular;
- vec4 diffuse = final_color;
- float envIntensity = final_normal.z;
-
- vec3 color = vec3(0,0,0);
-
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
-
- float bloom = 0.0;
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
-
- calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
-
- // This call breaks the Mac GLSL compiler/linker for unknown reasons (17Mar2020)
- // The call is either a no-op or a pure (pow) gamma adjustment, depending on GPU level
- // TODO: determine if we want to re-apply the gamma adjustment, and if so understand & fix Mac breakage
- //color = fullbrightScaleSoftClip(color);
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- //we're in sRGB space, so gamma correct this dot product so
- // lighting from the sun stays sharp
- float da = clamp(dot(normalize(norm.xyz), light_dir.xyz), 0.0, 1.0);
- da = pow(da, 1.0 / 1.3);
-
- color = amblit;
-
- //darken ambient for normals perpendicular to light vector so surfaces in shadow
- // and facing away from light still have some definition to them.
- // do NOT gamma correct this dot product so ambient lighting stays soft
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
-
- vec3 sun_contrib = min(da, shadow) * sunlit;
-
- color *= ambient;
-
- color += sun_contrib;
-
- color *= gamma_diff.rgb;
-
- float glare = 0.0;
-
- if (spec.a > 0.0) // specular reflection
- {
- /* // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020
- // Preserving the refactored version as a comment for potential reconsideration,
- // overriding the general rule to avoid pollutiong the source with commented code.
- //
- // If you're reading this in 2021+, feel free to obliterate.
-
- vec3 npos = -normalize(pos.xyz);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(light_dir.xyz + npos);
- float nh = dot(norm.xyz, h);
- float nv = dot(norm.xyz, 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);
- vec3 sp = sun_contrib*scol / 6.0f;
- sp = clamp(sp, vec3(0), vec3(1));
- bloom = dot(sp, sp) / 4.0;
- color += sp * spec.rgb;
- }
- */
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
-
- glare = max(spec_contrib.r, spec_contrib.g);
- glare = max(glare, spec_contrib.b);
-
- color += spec_contrib;
- }
-
- color = mix(color.rgb, diffcol.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- {
- //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
- vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
-
- color = mix(color, reflected_color, envIntensity);
-
- float cur_glare = max(reflected_color.r, reflected_color.g);
- cur_glare = max(cur_glare, reflected_color.b);
- cur_glare *= envIntensity*4.0;
- glare += cur_glare;
- }
-
- color = atmosFragLighting(color, additive, atten);
- color = scaleSoftClipFrag(color);
-
- //convert to linear before adding local lights
- color = srgb_to_linear(color);
-
- vec3 npos = normalize(-pos.xyz);
-
- vec3 light = vec3(0, 0, 0);
-
- final_specular.rgb = srgb_to_linear(final_specular.rgb); // SL-14035
-
-#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_attenuation[i].w );
-
- LIGHT_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
-
- color += light;
-
- glare = min(glare, 1.0);
- float al = max(diffcol.a, glare)*vertex_color.a;
-
- //convert to srgb as this color is being written post gamma correction
- color = linear_to_srgb(color);
-
-#ifdef WATER_FOG
- vec4 temp = applyWaterFogView(pos, vec4(color, al));
- color = temp.rgb;
- al = temp.a;
-#endif
-
- frag_color = vec4(color, al);
-
-#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
-
- // deferred path
- frag_data[0] = final_color; //gbuffer is sRGB
- frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
- frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
+ // emissive red PBR material
+ frag_data[0] = vec4(0, 0, 0, 0);
+ frag_data[1] = vec4(0, 0, 0, 0);
+ frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+ frag_data[3] = vec4(1, 0, 0, 0);
#endif
}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index 7e29ada205..a1cab87092 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -1,5 +1,5 @@
/**
- * @file bumpV.glsl
+ * @file materialV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
index 35068899ee..b4044353b4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -34,8 +34,7 @@ out vec4 frag_data[3];
#endif
uniform vec4 color;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 moonlight_color;
uniform vec3 moon_dir;
uniform float moon_brightness;
uniform sampler2D diffuseMap;
@@ -66,7 +65,7 @@ void main()
frag_data[0] = vec4(c.rgb, c.a);
frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
gl_FragDepth = 0.999985f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 09c47165dd..0ae4bbfc5d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -36,7 +36,6 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
-uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index ec3fb9c543..8dcc18080d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -42,7 +42,6 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
uniform sampler2D lightFunc;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
index 8f32dfde79..fc1024f4f1 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/shVisV.glsl
+ * @file class1\deferred\pbralphaF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -22,12 +22,13 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-ATTRIBUTE vec3 position;
-VARYING vec4 vary_pos;
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
void main()
{
- // Output
- vary_pos = vec4(position, 1);
- gl_Position = vary_pos;
+ frag_color = vec4(0,1,0,0.5);
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
new file mode 100644
index 0000000000..d0d76fd0cb
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
@@ -0,0 +1,115 @@
+/**
+ * @file class1\deferred\pbralphaV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+#ifdef HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+uniform mat4 modelview_projection_matrix;
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ #if !defined(HAS_SKIN)
+ uniform mat4 modelview_matrix;
+ #endif
+ VARYING vec3 vary_position;
+#endif
+
+uniform mat4 texture_matrix0;
+
+#ifdef HAS_SUN_SHADOW
+VARYING vec3 vary_fragcoord;
+uniform float near_clip;
+#endif
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 tangent;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec3 vary_normal;
+VARYING vec3 vary_tangent;
+flat out float vary_sign;
+
+
+void main()
+{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ vary_position = pos;
+#endif
+ vec4 vert = projection_matrix * vec4(pos,1.0);
+#else
+ //transform vertex
+ vec4 vert = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
+ gl_Position = vert;
+
+#ifdef HAS_SUN_SHADOW
+ vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip);
+#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+ vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+
+#ifdef HAS_SKIN
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
+#else //HAS_SKIN
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
+#endif //HAS_SKIN
+
+ vary_tangent = normalize(t);
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
+
+ vertex_color = diffuse_color;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ #if !defined(HAS_SKIN)
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+ #endif
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
new file mode 100644
index 0000000000..7376e9eb47
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
@@ -0,0 +1,105 @@
+/**
+ * @file pbropaqueF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+uniform sampler2D diffuseMap; //always in sRGB space
+
+uniform float metallicFactor;
+uniform float roughnessFactor;
+uniform vec3 emissiveColor;
+uniform sampler2D bumpMap;
+uniform sampler2D emissiveMap;
+uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness
+
+out vec4 frag_data[4];
+
+VARYING vec3 vary_position;
+VARYING vec4 vertex_color;
+VARYING vec3 vary_normal;
+VARYING vec3 vary_tangent;
+flat in float vary_sign;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+
+vec2 encode_normal(vec3 n);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+uniform mat3 normal_matrix;
+
+void main()
+{
+// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
+// else
+ vec4 albedo = texture2D(diffuseMap, vary_texcoord0.xy).rgba;
+ if (albedo.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ vec3 col = vertex_color.rgb * srgb_to_linear(albedo.rgb);
+
+ // from mikktspace.com
+ vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ // RGB = Occlusion, Roughness, Metal
+ // default values, see LLViewerTexture::sDefaultPBRORMImagep
+ // occlusion 1.0
+ // roughness 0.0
+ // metal 0.0
+ vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb;
+
+ spec.g *= roughnessFactor;
+ spec.b *= metallicFactor;
+
+ vec3 emissive = emissiveColor;
+ emissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb);
+
+ tnorm *= gl_FrontFacing ? 1.0 : -1.0;
+
+ //spec.rgb = vec3(1,1,0);
+ //col = vec3(0,0,0);
+ //emissive = vary_tangent.xyz*0.5+0.5;
+ //emissive = vec3(sign*0.5+0.5);
+ //emissive = vNt * 0.5 + 0.5;
+ //emissive = tnorm*0.5+0.5;
+ // See: C++: addDeferredAttachments(), GLSL: softenLightF
+ frag_data[0] = vec4(col, 0.0); // Diffuse
+ frag_data[1] = vec4(spec.rgb,vertex_color.a); // PBR linear packed Occlusion, Roughness, Metal.
+ frag_data[2] = vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags
+ frag_data[3] = vec4(emissive,0); // PBR sRGB Emissive
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
new file mode 100644
index 0000000000..5573c02a60
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
@@ -0,0 +1,92 @@
+/**
+ * @file pbropaqueV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+#ifdef HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+uniform mat4 modelview_projection_matrix;
+#endif
+
+uniform mat4 texture_matrix0;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 tangent;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+
+VARYING vec4 vertex_color;
+
+VARYING vec3 vary_tangent;
+flat out float vary_sign;
+VARYING vec3 vary_normal;
+
+void main()
+{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+
+ mat = modelview_matrix * mat;
+
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+
+ gl_Position = projection_matrix*vec4(pos,1.0);
+
+#else
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+ vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+#ifdef HAS_SKIN
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
+#else //HAS_SKIN
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
+#endif
+
+ vary_tangent = normalize(t);
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
+
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 18616a9bb3..5bb034d5c1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file pointLightF.glsl
+ * @file class1\deferred\pointLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -36,7 +36,6 @@ out vec4 frag_color;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
uniform sampler2DRect depthMap;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index cd37a34e0d..b61f37fe47 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -41,12 +41,53 @@ uniform float display_gamma;
vec3 linear_to_srgb(vec3 cl);
+//=================================
+// borrowed noise from:
+// <https://www.shadertoy.com/view/4dS3Wd>
+// By Morgan McGuire @morgan3d, http://graphicscodex.com
+//
+float hash(float n) { return fract(sin(n) * 1e4); }
+float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); }
+
+float noise(float x) {
+ float i = floor(x);
+ float f = fract(x);
+ float u = f * f * (3.0 - 2.0 * f);
+ return mix(hash(i), hash(i + 1.0), u);
+}
+
+float noise(vec2 x) {
+ vec2 i = floor(x);
+ vec2 f = fract(x);
+
+ // Four corners in 2D of a tile
+ float a = hash(i);
+ float b = hash(i + vec2(1.0, 0.0));
+ float c = hash(i + vec2(0.0, 1.0));
+ float d = hash(i + vec2(1.0, 1.0));
+
+ // Simple 2D lerp using smoothstep envelope between the values.
+ // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)),
+ // mix(c, d, smoothstep(0.0, 1.0, f.x)),
+ // smoothstep(0.0, 1.0, f.y)));
+
+ // Same code, with the clamps in smoothstep and common subexpressions
+ // optimized away.
+ vec2 u = f * f * (3.0 - 2.0 * f);
+ return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
+}
+
+//=============================
+
void main()
{
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
- //diff.rgb = pow(diff.rgb, vec3(display_gamma));
diff.rgb = linear_to_srgb(diff.rgb);
+ vec3 seed = (diff.rgb+vec3(1.0))*vec3(vary_fragcoord.xy, vary_fragcoord.x+vary_fragcoord.y);
+ vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb));
+ diff.rgb += nz*0.008;
+ //diff.rgb = nz;
frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
new file mode 100644
index 0000000000..dd850ff97c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
@@ -0,0 +1,58 @@
+/**
+ * @file class1/deferred/reflectionProbeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+// fallback stub -- will be used if actual reflection probe shader failed to load (output pink so it's obvious)
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+{
+ ambenv = vec3(1,0,1);
+ glossenv = vec3(1,0,1);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness)
+{
+ sampleReflectionProbes(ambenv, glossenv,
+ pos, norm, glossiness, false);
+}
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity)
+{
+ ambenv = vec3(1,0,1);
+ glossenv = vec3(1,0,1);
+ legacyenv = vec3(1,0,1);
+}
+
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
+{
+
+}
+
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity)
+{
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 331249dc33..adc2db60b6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -35,7 +35,7 @@ out vec4 frag_data[3];
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_HazeColor;
+VARYING vec3 vary_HazeColor;
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light);
@@ -48,7 +48,7 @@ void main()
// the fragment) if the sky wouldn't show up because the clouds
// are fully opaque.
- vec4 color;
+ vec3 color;
color = vary_HazeColor;
color.rgb *= 2.;
@@ -57,7 +57,7 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 0.0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog
+ frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog
gl_FragDepth = 0.99999f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index 28a1faf24f..ff53646fd4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -32,18 +32,18 @@ ATTRIBUTE vec3 position;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_HazeColor;
+VARYING vec3 vary_HazeColor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -52,11 +52,9 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
-
// NOTE: Keep these in sync!
// indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
// indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
@@ -87,17 +85,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
- vec4 light_atten;
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec3 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);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -125,21 +123,21 @@ void main()
// For sun, add to glow. For moon, remove glow entirely. SL-13768
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
- vec4 color =
+ vec3 color =
(blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
- tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+ vec3 tmpAmbient = ambient_color;
+ tmpAmbient += max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// Attenuate cloud color by atmosphere
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 7f2c603f87..4b34e55efd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -142,7 +142,7 @@ void main()
color = mix(color.rgb, reflected_color, envIntensity);
}
- if (norm.w < 0.5)
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
{
color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
@@ -156,12 +156,6 @@ void main()
}
-// linear debuggables
-//color.rgb = vec3(final_da);
-//color.rgb = vec3(ambient);
-//color.rgb = vec3(scol);
-//color.rgb = diffuse_srgb.rgb;
-
// convert to linear as fullscreen lights need to sum in linear colorspace
// and will be gamma (re)corrected downstream...
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index bac79a9fdc..ef9cee3fa0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
@@ -60,7 +60,7 @@ void main()
frag_data[0] = col;
frag_data[1] = vec4(0.0f);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
gl_FragDepth = 0.99995f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
index b2fa5d8a25..4ab8747629 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -57,7 +57,7 @@ void main()
frag_data[0] = c;
frag_data[1] = vec4(0.0f);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
gl_FragDepth = 0.999988f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 6b6eed9db8..d6c14c48c9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -63,6 +63,6 @@ void main()
frag_data[0] = outColor;
frag_data[1] = vec4(0.0,0.0,0.0,-1.0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 89e354558a..dc0e5b0ce3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -52,5 +52,5 @@ void main()
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
index 9a5debb3c1..14c337e608 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
@@ -78,5 +78,5 @@ void main()
frag_data[0] = vec4(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, env intens, atmo kill
+ frag_data[2] = vec4(encode_normal(wavef), 0.0, GBUFFER_FLAG_HAS_ATMOS); // normalxyz, env intens, flags (atmo kill)
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index a157e9c017..876422f86b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -22,163 +22,15 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-#extension GL_ARB_texture_rectangle : enable
-/*[EXTRA_CODE_HERE]*/
+// debug stub
+out vec4 frag_data[4];
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-vec3 scaleSoftClip(vec3 inColor);
-vec3 atmosTransport(vec3 inColor);
-
-uniform sampler2D bumpMap;
-uniform sampler2D bumpMap2;
-uniform float blend_factor;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-uniform float sunAngle;
-uniform float sunAngle2;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform float refScale;
-uniform float kd;
-uniform vec2 screenRes;
-uniform vec3 normScale;
-uniform float fresnelScale;
-uniform float fresnelOffset;
-uniform float blurMultiplier;
-uniform vec2 screen_res;
-uniform mat4 norm_mat; //region space to screen space
-uniform int water_edge;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-VARYING vec4 vary_position;
-
-vec2 encode_normal(vec3 n);
-vec3 scaleSoftClip(vec3 l);
-vec3 srgb_to_linear(vec3 c);
-vec3 linear_to_srgb(vec3 c);
-
-vec3 BlendNormal(vec3 bump1, vec3 bump2)
+void main()
{
- vec3 n = mix(bump1, bump2, blend_factor);
- return n;
-}
-
-void main()
-{
- vec4 color;
- float dist = length(view.xyz);
-
- //normalize view vector
- vec3 viewVec = normalize(view.xyz);
-
- //get wave normals
- vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
-
-
- vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
-
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
-
- //get base fresnel components
-
- vec3 df = vec3(
- dot(viewVec, wave1),
- dot(viewVec, (wave2 + wave3) * 0.5),
- dot(viewVec, wave3)
- ) * fresnelScale + fresnelOffset;
- df *= df;
-
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- vec2 dmod_scale = vec2(dmod*dmod, dmod);
-
- //get reflected color
- vec2 refdistort1 = wave1.xy*normScale.x;
- vec2 refvec1 = distort+refdistort1/dmod_scale;
- vec4 refcol1 = texture2D(refTex, refvec1);
-
- vec2 refdistort2 = wave2.xy*normScale.y;
- vec2 refvec2 = distort+refdistort2/dmod_scale;
- vec4 refcol2 = texture2D(refTex, refvec2);
-
- vec2 refdistort3 = wave3.xy*normScale.z;
- vec2 refvec3 = distort+refdistort3/dmod_scale;
- vec4 refcol3 = texture2D(refTex, refvec3);
-
- vec4 refcol = refcol1 + refcol2 + refcol3;
- float df1 = df.x + df.y + df.z;
- refcol *= df1 * 0.333;
-
- vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
- wavef.z *= max(-viewVec.z, 0.1);
- wavef = normalize(wavef);
-
- float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-
- vec2 refdistort4 = wavef.xy*0.125;
- refdistort4.y -= abs(refdistort4.y);
- 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);
-
- //harden specular
- spec = pow(spec, 128.0);
-
- //figure out distortion vector (ripply)
- vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
-
- vec4 fb = texture2D(screenTex, distort2);
-
- //mix with reflection
- // 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.99999f);
-
- vec4 pos = vary_position;
-
- color.rgb += spec * specular;
-
- color.rgb = atmosTransport(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
-
- color.a = spec * sunAngle2;
-
- vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
-
- //frag_data[0] = color;
-
- // TODO: The non-obvious assignment below is copied from the pre-EEP WL shader code
- // Unfortunately, fixing it causes a mismatch for EEP, and so it remains... for now
- // SL-12975 (unfix pre-EEP broken alpha)
- frag_data[0] = vec4(color.rgb, color); // Effectively, color.rgbr
-
-
- frag_data[1] = vec4(0); // speccolor, spec
- frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, 0);// normalxy, 0, 0
+ // emissive blue PBR material
+ frag_data[0] = vec4(0, 0, 0, 0);
+ frag_data[1] = vec4(0, 0, 0, 0);
+ frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+ frag_data[3] = vec4(0, 0, 1, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 8c8bd6d0d5..ad105c616c 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
@@ -23,55 +23,10 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#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 waterFogKS;
-uniform vec2 screenRes;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-vec4 applyWaterFogView(vec3 pos, vec4 color);
+// debug stub
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_color = applyWaterFogView(view.xyz, fb);
+ frag_color = vec4(0, 1, 1, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index d370997123..46a6c2021d 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
@@ -23,146 +23,9 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-vec3 scaleSoftClip(vec3 inColor);
-vec3 atmosTransport(vec3 inColor);
-
-uniform sampler2D bumpMap;
-uniform sampler2D bumpMap2;
-uniform float blend_factor;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-
-uniform float sunAngle;
-uniform float sunAngle2;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform float refScale;
-uniform float kd;
-uniform vec2 screenRes;
-uniform vec3 normScale;
-uniform float fresnelScale;
-uniform float fresnelOffset;
-uniform float blurMultiplier;
-
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-vec3 BlendNormal(vec3 bump1, vec3 bump2)
+void main()
{
- vec3 n = mix(bump1, bump2, blend_factor);
- return n;
+ frag_color = vec4(0, 0, 1, 0);
}
-
-
-void main()
-{
- vec4 color;
-
- float dist = length(view.xy);
-
- //normalize view vector
- vec3 viewVec = normalize(view.xyz);
-
- //get wave normals
- vec2 bigwave = vec2(refCoord.w, view.w);
- vec3 wave1_a = texture2D(bumpMap, bigwave ).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
-
-
- vec3 wave1_b = texture2D(bumpMap2, bigwave ).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
-
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
-
-
- //get base fresnel components
-
- vec3 df = vec3(
- dot(viewVec, wave1),
- dot(viewVec, (wave2 + wave3) * 0.5),
- dot(viewVec, wave3)
- ) * fresnelScale + fresnelOffset;
- df *= df;
-
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- vec2 dmod_scale = vec2(dmod*dmod, dmod);
-
- //get reflected color
- vec2 refdistort1 = wave1.xy*normScale.x;
- vec2 refvec1 = distort+refdistort1/dmod_scale;
- vec4 refcol1 = texture2D(refTex, refvec1);
-
- vec2 refdistort2 = wave2.xy*normScale.y;
- vec2 refvec2 = distort+refdistort2/dmod_scale;
- vec4 refcol2 = texture2D(refTex, refvec2);
-
- vec2 refdistort3 = wave3.xy*normScale.z;
- vec2 refvec3 = distort+refdistort3/dmod_scale;
- vec4 refcol3 = texture2D(refTex, refvec3);
-
- vec4 refcol = refcol1 + refcol2 + refcol3;
- float df1 = df.x + df.y + df.z;
- refcol *= df1 * 0.333;
-
- vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
-
- wavef.z *= max(-viewVec.z, 0.1);
- wavef = normalize(wavef);
-
- float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-
- vec2 refdistort4 = wavef.xy*0.125;
- refdistort4.y -= abs(refdistort4.y);
- 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);
-
- //harden specular
- spec = pow(spec, 128.0);
-
- //figure out distortion vector (ripply)
- vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
-
- vec4 fb = texture2D(screenTex, distort2);
-
- //mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
- color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
- color.rgb += spec * specular;
-
- color.rgb = atmosTransport(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
- color.a = spec * sunAngle2;
-
- frag_color = color;
-
-#if defined(WATER_EDGE)
- gl_FragDepth = 0.9999847f;
-#endif
-
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index df640cba05..011b3c8643 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -32,6 +32,8 @@ uniform float waterFogKS;
vec3 getPositionEye();
+vec3 srgb_to_linear(vec3 col);
+
vec4 applyWaterFogView(vec3 pos, vec4 color)
{
vec3 view = normalize(pos);
@@ -71,6 +73,52 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)
return color;
}
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
+{
+ if (dot(pos, waterPlane.xyz) + waterPlane.w > 0.0)
+ {
+ return color;
+ }
+
+ vec3 view = normalize(pos);
+ //normalize view vector
+ 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;
+ kc.rgb = srgb_to_linear(kc.rgb); // TODO -- pass in waterFogColor linear
+
+ 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;
+}
+
vec4 applyWaterFog(vec4 color)
{
//normalize view vector
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index cc41e3f740..a0a0e7dfca 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -24,6 +24,7 @@
*/
uniform mat4 modelview_matrix;
+uniform mat3 normal_matrix;
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
@@ -36,10 +37,16 @@ uniform vec2 waveDir2;
uniform float time;
uniform vec3 eyeVec;
uniform float waterHeight;
+uniform vec3 lightDir;
VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
+out vec3 vary_position;
+out vec3 vary_light_dir;
+out vec3 vary_tangent;
+out vec3 vary_normal;
+out vec2 vary_fragcoord;
float wave(vec2 v, float t, float f, vec2 d, float s)
{
@@ -52,6 +59,11 @@ void main()
vec4 pos = vec4(position.xyz, 1.0);
mat4 modelViewProj = modelview_projection_matrix;
+ vary_position = (modelview_matrix * pos).xyz;
+ vary_light_dir = normal_matrix * lightDir;
+ vary_normal = normal_matrix * vec3(0, 0, 1);
+ vary_tangent = normal_matrix * vec3(1, 0, 0);
+
vec4 oPosition;
//get view vector
@@ -63,12 +75,13 @@ void main()
pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
view.xyz = oEyeVec;
-
+
d = clamp(ld/1536.0-0.5, 0.0, 1.0);
d *= d;
oPosition = vec4(position, 1.0);
oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
+
oPosition = modelViewProj * oPosition;
refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
@@ -83,8 +96,7 @@ void main()
pos = modelview_matrix*pos;
calcAtmospherics(pos.xyz);
-
-
+
//pass wave parameters to pixel shader
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + waveDir1 * time * 0.055;
//get two normal map (detail map) texture coordinates
diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
new file mode 100644
index 0000000000..feaf562686
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
@@ -0,0 +1,227 @@
+/**
+ * @file irradianceGenF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+
+/*[EXTRA_CODE_HERE]*/
+
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform samplerCubeArray reflectionProbes;
+uniform int sourceIdx;
+
+VARYING vec3 vary_dir;
+
+
+// Code below is derived from the Khronos GLTF Sample viewer:
+// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/shaders/ibl_filtering.frag
+
+
+#define MATH_PI 3.1415926535897932384626433832795
+
+float u_roughness = 1.0;
+int u_sampleCount = 16;
+float u_lodBias = 2.0;
+int u_width = 64;
+
+// Hammersley Points on the Hemisphere
+// CC BY 3.0 (Holger Dammertz)
+// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+// with adapted interface
+float radicalInverse_VdC(uint bits)
+{
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ return float(bits) * 2.3283064365386963e-10; // / 0x100000000
+}
+
+// hammersley2d describes a sequence of points in the 2d unit square [0,1)^2
+// that can be used for quasi Monte Carlo integration
+vec2 hammersley2d(int i, int N) {
+ return vec2(float(i)/float(N), radicalInverse_VdC(uint(i)));
+}
+
+// Hemisphere Sample
+
+// TBN generates a tangent bitangent normal coordinate frame from the normal
+// (the normal must be normalized)
+mat3 generateTBN(vec3 normal)
+{
+ vec3 bitangent = vec3(0.0, 1.0, 0.0);
+
+ float NdotUp = dot(normal, vec3(0.0, 1.0, 0.0));
+ float epsilon = 0.0000001;
+ /*if (1.0 - abs(NdotUp) <= epsilon)
+ {
+ // Sampling +Y or -Y, so we need a more robust bitangent.
+ if (NdotUp > 0.0)
+ {
+ bitangent = vec3(0.0, 0.0, 1.0);
+ }
+ else
+ {
+ bitangent = vec3(0.0, 0.0, -1.0);
+ }
+ }*/
+
+ vec3 tangent = normalize(cross(bitangent, normal));
+ bitangent = cross(normal, tangent);
+
+ return mat3(tangent, bitangent, normal);
+}
+
+struct MicrofacetDistributionSample
+{
+ float pdf;
+ float cosTheta;
+ float sinTheta;
+ float phi;
+};
+
+MicrofacetDistributionSample Lambertian(vec2 xi, float roughness)
+{
+ MicrofacetDistributionSample lambertian;
+
+ // Cosine weighted hemisphere sampling
+ // http://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/2D_Sampling_with_Multidimensional_Transformations.html#Cosine-WeightedHemisphereSampling
+ lambertian.cosTheta = sqrt(1.0 - xi.y);
+ lambertian.sinTheta = sqrt(xi.y); // equivalent to `sqrt(1.0 - cosTheta*cosTheta)`;
+ lambertian.phi = 2.0 * MATH_PI * xi.x;
+
+ lambertian.pdf = lambertian.cosTheta / MATH_PI; // evaluation for solid angle, therefore drop the sinTheta
+
+ return lambertian;
+}
+
+
+// getImportanceSample returns an importance sample direction with pdf in the .w component
+vec4 getImportanceSample(int sampleIndex, vec3 N, float roughness)
+{
+ // generate a quasi monte carlo point in the unit square [0.1)^2
+ vec2 xi = hammersley2d(sampleIndex, u_sampleCount);
+
+ MicrofacetDistributionSample importanceSample;
+
+ // generate the points on the hemisphere with a fitting mapping for
+ // the distribution (e.g. lambertian uses a cosine importance)
+ importanceSample = Lambertian(xi, roughness);
+
+ // transform the hemisphere sample to the normal coordinate frame
+ // i.e. rotate the hemisphere to the normal direction
+ vec3 localSpaceDirection = normalize(vec3(
+ importanceSample.sinTheta * cos(importanceSample.phi),
+ importanceSample.sinTheta * sin(importanceSample.phi),
+ importanceSample.cosTheta
+ ));
+ mat3 TBN = generateTBN(N);
+ vec3 direction = TBN * localSpaceDirection;
+
+ return vec4(direction, importanceSample.pdf);
+}
+
+// Mipmap Filtered Samples (GPU Gems 3, 20.4)
+// https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling
+// https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
+float computeLod(float pdf)
+{
+ // // Solid angle of current sample -- bigger for less likely samples
+ // float omegaS = 1.0 / (float(u_sampleCount) * pdf);
+ // // Solid angle of texel
+ // // note: the factor of 4.0 * MATH_PI
+ // float omegaP = 4.0 * MATH_PI / (6.0 * float(u_width) * float(u_width));
+ // // Mip level is determined by the ratio of our sample's solid angle to a texel's solid angle
+ // // note that 0.5 * log2 is equivalent to log4
+ // float lod = 0.5 * log2(omegaS / omegaP);
+
+ // babylon introduces a factor of K (=4) to the solid angle ratio
+ // this helps to avoid undersampling the environment map
+ // this does not appear in the original formulation by Jaroslav Krivanek and Mark Colbert
+ // log4(4) == 1
+ // lod += 1.0;
+
+ // We achieved good results by using the original formulation from Krivanek & Colbert adapted to cubemaps
+
+ // https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
+ float lod = 0.5 * log2( 6.0 * float(u_width) * float(u_width) / (float(u_sampleCount) * pdf));
+
+
+ return lod;
+}
+
+vec4 filterColor(vec3 N)
+{
+ //return textureLod(uCubeMap, N, 3.0).rgb;
+ vec4 color = vec4(0.f);
+ float weight = 0.0f;
+
+ for(int i = 0; i < u_sampleCount; ++i)
+ {
+ vec4 importanceSample = getImportanceSample(i, N, 1.0);
+
+ vec3 H = vec3(importanceSample.xyz);
+ float pdf = importanceSample.w;
+
+ // mipmap filtered samples (GPU Gems 3, 20.4)
+ float lod = computeLod(pdf);
+
+ // apply the bias to the lod
+ lod += u_lodBias;
+
+ lod = clamp(lod, 0, 6);
+ // sample lambertian at a lower resolution to avoid fireflies
+ vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod);
+
+ color += lambertian;
+ }
+
+ if(weight != 0.0f)
+ {
+ color /= weight;
+ }
+ else
+ {
+ color /= float(u_sampleCount);
+ }
+
+ return color;
+}
+
+// entry point
+void main()
+{
+ vec4 color = vec4(0);
+
+ color = filterColor(vary_dir);
+
+ frag_color = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl
index b466883dc7..5190abf17c 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl
@@ -1,9 +1,9 @@
/**
- * @file genSkyShV.glsl
+ * @file irradianceGenV.glsl
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,16 +22,17 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+uniform mat4 modelview_matrix;
+
ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-VARYING vec2 vary_frag;
+VARYING vec3 vary_dir;
void main()
{
- // pass through untransformed fullscreen pos
- gl_Position = vec4(position.xyz, 1.0);
- vary_frag = texcoord0;
+ gl_Position = vec4(position, 1.0);
+
+ vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
index db130e456c..f5d2804c7f 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
@@ -23,13 +23,13 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
+out vec4 frag_data[4];
void main()
{
- frag_color = vec4(1,1,1,1);
+ // emissive red PBR material for debugging
+ frag_data[0] = vec4(0, 0, 0, 0);
+ frag_data[1] = vec4(0, 0, 0, 0);
+ frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+ frag_data[3] = vec4(1, 0, 0, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
new file mode 100644
index 0000000000..32f157e9d2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -0,0 +1,169 @@
+/**
+ * @file radianceGenF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+uniform samplerCubeArray reflectionProbes;
+uniform int sourceIdx;
+
+VARYING vec3 vary_dir;
+
+//uniform float roughness;
+
+uniform float mipLevel;
+
+// =============================================================================================================
+// Parts of this file are (c) 2018 Sascha Willems
+// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/prefilterenvmap.frag
+/*
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+// =============================================================================================================
+
+const float PI = 3.1415926536;
+
+// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+float random(vec2 co)
+{
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
+}
+
+vec2 hammersley2d(uint i, uint N)
+{
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
+}
+
+// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+{
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+}
+
+// Normal Distribution function
+float D_GGX(float dotNH, float roughness)
+{
+ float alpha = roughness * roughness;
+ float alpha2 = alpha * alpha;
+ float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
+ return (alpha2)/(PI * denom*denom);
+}
+
+vec4 prefilterEnvMap(vec3 R)
+{
+ vec3 N = R;
+ vec3 V = R;
+ vec4 color = vec4(0.0);
+ float totalWeight = 0.0;
+ float envMapDim = 256.0;
+ int numSamples = 4;
+
+ float numMips = 6.0;
+
+ float roughness = mipLevel/numMips;
+
+ numSamples = max(int(numSamples*roughness), 1);
+
+ for(uint i = 0u; i < numSamples; i++) {
+ vec2 Xi = hammersley2d(i, numSamples);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+ float dotNL = clamp(dot(N, L), 0.0, 1.0);
+ if(dotNL > 0.0) {
+ // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
+
+ float dotNH = clamp(dot(N, H), 0.0, 1.0);
+ float dotVH = clamp(dot(V, H), 0.0, 1.0);
+
+ // Probability Distribution Function
+ float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001;
+ // Slid angle of current smple
+ float omegaS = 1.0 / (float(numSamples) * pdf);
+ // Solid angle of 1 pixel across all cube faces
+ float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
+ // Biased (+1.0) mip level for better result
+ float mip = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, numMips);
+ //float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f);
+ color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip) * dotNL;
+ totalWeight += dotNL;
+
+ }
+ }
+ return (color / totalWeight);
+}
+
+void main()
+{
+ vec3 N = normalize(vary_dir);
+ frag_color = prefilterEnvMap(N);
+}
+// =============================================================================================================
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl
index 2eb222ada4..5f5d9396ff 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/skyV.glsl
+ * @file radianceGenV.glsl
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,16 +22,17 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+uniform mat4 modelview_matrix;
+
ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-VARYING vec2 vary_frag;
+VARYING vec3 vary_dir;
void main()
{
- // pass through untransformed fullscreen pos at back of frustum for proper sky depth testing
- gl_Position = vec4(position.xy, 1.0f, 1.0);
- vary_frag = texcoord0;
+ gl_Position = vec4(position, 1.0);
+
+ vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
new file mode 100644
index 0000000000..9dd97a80b2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
@@ -0,0 +1,101 @@
+/**
+ * @file reflectionmipF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+// NOTE screenMap should always be texture channel 0 and
+// depthmap should always be channel 1
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect depthMap;
+
+uniform float resScale;
+uniform float znear;
+uniform float zfar;
+
+VARYING vec2 vary_texcoord0;
+
+// get linear depth value given a depth buffer sample d and znear and zfar values
+float linearDepth(float d, float znear, float zfar);
+
+void main()
+{
+#if 0
+ float w[9];
+
+ float c = 1.0/16.0; //corner weight
+ float e = 1.0/8.0; //edge weight
+ float m = 1.0/4.0; //middle weight
+
+ //float wsum = c*4+e*4+m;
+
+ w[0] = c; w[1] = e; w[2] = c;
+ w[3] = e; w[4] = m; w[5] = e;
+ w[6] = c; w[7] = e; w[8] = c;
+
+ vec2 tc[9];
+
+ float ed = 1;
+ float cd = 1;
+
+
+ tc[0] = vec2(-cd, cd); tc[1] = vec2(0, ed); tc[2] = vec2(cd, cd);
+ tc[3] = vec2(-ed, 0); tc[4] = vec2(0, 0); tc[5] = vec2(ed, 0);
+ tc[6] = vec2(-cd, -cd); tc[7] = vec2(0, -ed); tc[8] = vec2(cd, -1);
+
+ vec3 color = vec3(0,0,0);
+
+ for (int i = 0; i < 9; ++i)
+ {
+ color += texture2DRect(screenMap, vary_texcoord0.xy+tc[i]).rgb * w[i];
+ //color += texture2DRect(screenMap, vary_texcoord0.xy+tc[i]*2.0).rgb * w[i]*0.5;
+ }
+
+ //color /= wsum;
+
+ frag_color = vec4(color, 1.0);
+#else
+ vec2 depth_tc = vary_texcoord0.xy * resScale;
+ float depth = texture(depthMap, depth_tc).r;
+ float dist = linearDepth(depth, znear, zfar);
+
+ // convert linear depth to distance
+ vec3 v;
+ v.xy = depth_tc / 512.0 * 2.0 - 1.0;
+ v.z = 1.0;
+ v = normalize(v);
+ dist /= v.z;
+
+ vec3 col = texture2DRect(diffuseRect, vary_texcoord0.xy).rgb;
+ frag_color = vec4(col, dist/256.0);
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
index ea2690ba09..12f500e224 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -22,113 +22,26 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-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 ssao_effect_mat;
-uniform int no_atmo;
-uniform float sun_moon_glow_factor;
+
+// debug stub
float getAmbientClamp() { return 1.0f; }
+// Returns colors in sRGB
void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive,
out vec3 atten, bool use_ao)
{
- vec3 rel_pos = inPositionEye;
-
- //(TERRAIN) limit altitude
- if (abs(rel_pos.y) > max_y) rel_pos *= (max_y / rel_pos.y);
-
- vec3 rel_pos_norm = normalize(rel_pos);
- float rel_pos_len = length(rel_pos);
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-
- // sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- vec4 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
-
- vec4 combined_haze = blue_density + vec4(haze_density);
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = vec4(haze_density) / combined_haze;
-
- //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain)
- float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y);
- sunlight *= exp(-light_atten * above_horizon_factor); // for sun [horizon..overhead] this maps to an exp curve [0..1]
-
- // main atmospheric scattering line integral
- float density_dist = rel_pos_len * density_multiplier;
-
- // Transparency (-> combined_haze)
- // ATI Bugfix -- can't store combined_haze*density_dist*distance_multiplier in a variable because the ati
- // compiler gets confused.
- combined_haze = exp(-combined_haze * density_dist * distance_multiplier);
-
- // final atmosphere attenuation factor
- atten = combined_haze.rgb;
-
- // compute haze glow
- float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
-
- // dampen sun additive contrib when not facing it...
- // SL-13539: This "if" clause causes an "additive" white artifact at roughly 77 degreees.
- // if (length(light_dir) > 0.01)
- haze_glow *= max(0.0f, dot(light_dir, rel_pos_norm));
-
- haze_glow = 1. - haze_glow;
- // haze_glow is 0 at the sun and increases away from sun
- haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- haze_glow *= glow.x;
- // higher glow.x gives dimmer glow (because next step is 1 / "angle")
- haze_glow = pow(haze_glow, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- // add "minimum anti-solar illumination"
- haze_glow += .25;
-
- haze_glow *= sun_moon_glow_factor;
-
- vec4 amb_color = ambient_color;
-
- // increase ambient when there are more clouds
- vec4 tmpAmbient = amb_color + (vec4(1.) - amb_color) * 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);
- */
- if (use_ao)
- {
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
- }
-
- // Similar/Shared Algorithms:
- // indra\llinventory\llsettingssky.cpp -- LLSettingsSky::calculateLightSettings()
- // indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars()
- // haze color
- vec3 cs = sunlight.rgb * (1. - cloud_shadow);
- additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
+ amblit = vec3(0.2, 0, 0.2);
+ sunlit = vec3(1,0,1);
+ additive = vec3(0.5,0.5,0.5);
+ atten = vec3(1,0,1);
+}
- // brightness of surface both sunlight and ambient
- sunlit = sunlight.rgb * 0.5;
- amblit = tmpAmbient.rgb * .25;
- additive *= vec3(1.0 - combined_haze);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+ out vec3 atten)
+{
+ amblit = vec3(0.2, 0, 0.2);
+ sunlit = vec3(1,0,1);
+ additive = vec3(0.5,0.5,0.5);
+ atten = vec3(1,0,1);
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
deleted file mode 100644
index 82fad4db5a..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * @file class1/windlight/cloudShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 sunlight_color;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-void main()
-{
- if (cloud_scale >= 0.0001)
- {
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = vec4(alpha1, alpha1, alpha1, 1);
- }
- else
- {
- frag_color = vec4(1);
- }
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
deleted file mode 100644
index 09b6004481..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file class1\windlight\cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
index 2425a2ad04..f03003f5e1 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
@@ -34,8 +34,7 @@ out vec4 frag_color;
#endif
uniform vec4 color;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 moonlight_color;
uniform vec3 moon_dir;
uniform float moon_brightness;
uniform sampler2D diffuseMap;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
new file mode 100644
index 0000000000..e255c78b86
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -0,0 +1,306 @@
+/**
+ * @file alphaF.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$
+ */
+
+//class2/deferred/alphaF.glsl
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#define INDEXED 1
+#define NON_INDEXED 2
+#define NON_INDEXED_NO_COLOR 3
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform mat3 env_mat;
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+
+#ifdef USE_DIFFUSE_TEX
+uniform sampler2D diffuseMap;
+#endif
+
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
+
+#ifdef USE_VERTEX_COLOR
+VARYING vec4 vertex_color; //vertex color should be treated as sRGB
+#endif
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha;
+#endif
+
+uniform mat4 proj_mat;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+uniform int sun_up_factor;
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec4 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+void waterClip(vec3 pos);
+
+#ifdef WATER_FOG
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+#endif
+
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+vec2 encode_normal (vec3 n);
+vec3 scaleSoftClipFragLinear(vec3 l);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+
+#ifdef HAS_SUN_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
+
+float getAmbientClamp();
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
+{
+ // SL-14895 inverted attenuation work-around
+ // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
+ // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
+ // to recover the `adjusted_radius` value previously being sent as la.
+ float falloff_factor = (12.0 * fa) - 9.0;
+ float inverted_la = falloff_factor / la;
+ // Yes, it makes me want to cry as well. DJH
+
+ vec3 col = vec3(0);
+
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float dist = length(lv);
+ float da = 1.0;
+
+ /*if (dist > inverted_la)
+ {
+ return col;
+ }
+
+ clip to projector bounds
+ vec4 proj_tc = proj_mat * lp;
+
+ if (proj_tc.z < 0
+ || proj_tc.z > 1
+ || proj_tc.x < 0
+ || proj_tc.x > 1
+ || proj_tc.y < 0
+ || proj_tc.y > 1)
+ {
+ return col;
+ }*/
+
+ if (dist > 0.0 && inverted_la > 0.0)
+ {
+ dist /= inverted_la;
+
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0f;
+
+ if (dist_atten <= 0.0)
+ {
+ return col;
+ }
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= dot(n, lv);
+ da = max(0.0, da);
+
+ float lit = 0.0f;
+
+ float amb_da = 0.0;//ambiance;
+ if (da > 0)
+ {
+ lit = max(da * dist_atten,0.0);
+ col = lit * light_col * diffuse;
+ amb_da += (da*0.5+0.5) * ambiance;
+ }
+ amb_da += (da*da*0.5 + 0.5) * ambiance;
+ amb_da *= dist_atten;
+ amb_da = min(amb_da, 1.0f - lit);
+
+ // SL-10969 ... need to work out why this blows out in many setups...
+ //col.rgb += amb_da * light_col * diffuse;
+
+ // no spec for alpha shader...
+ }
+ col = max(col, vec3(0));
+ return col;
+}
+
+void main()
+{
+ vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+ frag *= screen_res;
+
+ vec4 pos = vec4(vary_position, 1.0);
+#ifndef IS_AVATAR_SKIN
+ // clip against water plane unless this is a legacy avatar skin
+ waterClip(pos.xyz);
+#endif
+ vec3 norm = vary_norm;
+
+ float shadow = 1.0f;
+
+#ifdef HAS_SUN_SHADOW
+ shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
+#endif
+
+#ifdef USE_DIFFUSE_TEX
+ vec4 diffuse_tap = texture2D(diffuseMap,vary_texcoord0.xy);
+#endif
+
+#ifdef USE_INDEXED_TEX
+ vec4 diffuse_tap = diffuseLookup(vary_texcoord0.xy);
+#endif
+
+ vec4 diffuse_srgb = diffuse_tap;
+
+#ifdef FOR_IMPOSTOR
+ vec4 color;
+ color.rgb = diffuse_srgb.rgb;
+ color.a = 1.0;
+
+ float final_alpha = diffuse_srgb.a * vertex_color.a;
+ diffuse_srgb.rgb *= vertex_color.rgb;
+
+ // Insure we don't pollute depth with invis pixels in impostor rendering
+ //
+ if (final_alpha < minimum_alpha)
+ {
+ discard;
+ }
+
+ color.rgb = diffuse_srgb.rgb;
+ color.a = final_alpha;
+
+#else // FOR_IMPOSTOR
+
+ vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir;
+
+ float final_alpha = diffuse_linear.a;
+
+#ifdef USE_VERTEX_COLOR
+ final_alpha *= vertex_color.a;
+
+ if (final_alpha < minimum_alpha)
+ { // TODO: figure out how to get invisible faces out of
+ // render batches without breaking glow
+ discard;
+ }
+
+ diffuse_srgb.rgb *= vertex_color.rgb;
+ diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
+#endif // USE_VERTEX_COLOR
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten);
+
+ vec3 irradiance;
+ vec3 glossenv;
+ vec3 legacyenv;
+ sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, pos.xyz, norm.xyz, 0.0, 0.0);
+
+
+ float da = dot(norm.xyz, light_dir.xyz);
+ da = clamp(da, -1.0, 1.0);
+
+ float final_da = da;
+ final_da = clamp(final_da, 0.0f, 1.0f);
+
+ vec4 color = vec4(0.0);
+
+ color.a = final_alpha;
+
+ vec3 sun_contrib = min(final_da, shadow) * sunlit;
+
+ color.rgb = max(amblit, irradiance);
+
+ color.rgb += sun_contrib;
+
+ color.rgb *= diffuse_linear.rgb;
+
+ color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+ color.rgb = scaleSoftClipFragLinear(color.rgb);
+
+ vec4 light = vec4(0,0,0,0);
+
+ #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ // sum local light contrib in linear colorspace
+#if !defined(LOCAL_LIGHT_KILL)
+ color.rgb += light.rgb;
+#endif // !defined(LOCAL_LIGHT_KILL)
+
+#ifdef WATER_FOG
+ color = applyWaterFogViewLinear(pos.xyz, color);
+#endif // WATER_FOG
+
+#endif // #else // FOR_IMPOSTOR
+
+ frag_color = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
new file mode 100644
index 0000000000..b39f834e41
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -0,0 +1,239 @@
+/**
+ * @file class1\deferred\pbralphaF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+uniform sampler2D diffuseMap; //always in sRGB space
+uniform sampler2D bumpMap;
+uniform sampler2D emissiveMap;
+uniform sampler2D specularMap; // PBR: Packed: Occlusion, Metal, Roughness
+
+uniform float metallicFactor;
+uniform float roughnessFactor;
+uniform vec3 emissiveColor;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+uniform sampler2DRect lightMap;
+#endif
+
+uniform int sun_up_factor;
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+
+out vec4 frag_color;
+
+#ifdef HAS_SUN_SHADOW
+ VARYING vec3 vary_fragcoord;
+ uniform vec2 screen_res;
+#endif
+
+VARYING vec3 vary_position;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec3 vary_normal;
+VARYING vec3 vary_tangent;
+flat in float vary_sign;
+
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+#endif
+
+// Lights
+// See: LLRender::syncLightState()
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8]; // spot direction
+uniform vec4 light_attenuation[8]; // linear, quadratic, is omni, unused, See: LLPipeline::setupHWLights() and syncLightState()
+uniform vec3 light_diffuse[8];
+uniform vec2 light_deferred_attenuation[8]; // light size and falloff
+
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness);
+
+void waterClip(vec3 pos);
+
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
+
+vec3 pbrBaseLight(vec3 diffuseColor,
+ vec3 specularColor,
+ float metallic,
+ vec3 pos,
+ vec3 norm,
+ float perceptualRoughness,
+ vec3 light_dir,
+ vec3 sunlit,
+ float scol,
+ vec3 radiance,
+ vec3 irradiance,
+ vec3 colorEmissive,
+ float ao,
+ vec3 additive,
+ vec3 atten);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 p, // pixel position
+ vec3 v, // view vector (negative normalized pixel position)
+ vec3 lp, // light position
+ vec3 ld, // light direction (for spotlights)
+ vec3 lightColor,
+ float lightSize, float falloff, float is_pointlight, float ambiance)
+{
+ vec3 color = vec3(0,0,0);
+
+ vec3 lv = lp.xyz - p;
+
+ float lightDist = length(lv);
+
+ float dist = lightDist / lightSize;
+ if (dist <= 1.0)
+ {
+ lv /= lightDist;
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ // spotlight coefficient.
+ float spot = max(dot(-ld, lv), is_pointlight);
+ // spot*spot => GL_SPOT_EXPONENT=2
+ float spot_atten = spot*spot;
+
+ vec3 intensity = spot_atten * dist_atten * lightColor * 3.0;
+
+ color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
+ }
+
+ return color;
+}
+
+void main()
+{
+ vec3 color = vec3(0,0,0);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ vec3 pos = vary_position;
+
+ waterClip(pos);
+
+// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
+// else
+ vec4 albedo = texture(diffuseMap, vary_texcoord0.xy).rgba;
+ albedo.rgb = srgb_to_linear(albedo.rgb);
+#ifdef HAS_ALPHA_MASK
+ if (albedo.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+ vec3 baseColor = vertex_color.rgb * albedo.rgb;
+
+ vec3 vNt = texture(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 norm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ norm *= gl_FrontFacing ? 1.0 : -1.0;
+
+ float scol = 1.0;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten);
+
+#ifdef HAS_SUN_SHADOW
+ vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+ frag *= screen_res;
+ scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
+#endif
+
+ vec3 orm = texture(specularMap, vary_texcoord2.xy).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
+
+ float perceptualRoughness = orm.g * roughnessFactor;
+ float metallic = orm.b * metallicFactor;
+ float ao = orm.r;
+
+ // emissiveColor is the emissive color factor from GLTF and is already in linear space
+ vec3 colorEmissive = emissiveColor;
+ // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear
+ colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb);
+
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, pos.xyz, norm.xyz, gloss);
+ // Take maximium of legacy ambient vs irradiance sample as irradiance
+ // NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
+ irradiance = max(amblit,irradiance);
+
+ vec3 diffuseColor;
+ vec3 specularColor;
+ calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);
+
+ vec3 v = -normalize(pos.xyz);
+ color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
+
+ vec3 light = vec3(0);
+
+ // Punctual lights
+#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ color.rgb += light.rgb;
+
+
+ frag_color = vec4(color.rgb,albedo.a * vertex_color.a);
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
new file mode 100644
index 0000000000..eb26143438
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
@@ -0,0 +1,75 @@
+/**
+ * @file class2/deferred/reflectionProbeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+// Implementation for when reflection probes are disabled
+
+uniform float reflection_probe_ambiance;
+
+uniform samplerCube environmentMap;
+
+uniform mat3 env_mat;
+
+vec3 srgb_to_linear(vec3 c);
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+{
+ ambenv = vec3(reflection_probe_ambiance * 0.25);
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 env_vec = env_mat * refnormpersp;
+ glossenv = srgb_to_linear(textureCube(environmentMap, env_vec).rgb);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness)
+{
+ sampleReflectionProbes(ambenv, glossenv,
+ pos, norm, glossiness, false);
+}
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity)
+{
+ ambenv = vec3(reflection_probe_ambiance * 0.25);
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 env_vec = env_mat * refnormpersp;
+
+ legacyenv = srgb_to_linear(textureCube(environmentMap, env_vec).rgb);
+
+ glossenv = legacyenv;
+}
+
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
+{
+
+}
+
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity)
+{
+ color = mix(color.rgb, legacyenv*1.5, envIntensity);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
index 6841a8194f..668f70c3ab 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
@@ -32,13 +32,13 @@ uniform mat4 modelview_projection_matrix;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -47,10 +47,10 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
+uniform vec3 cloud_color;
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -123,16 +123,16 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y);
@@ -162,7 +162,7 @@ void main()
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
// Haze color above cloud
- vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color)
+ vec3 color = blue_horizon * blue_weight * (sunlight + ambient_color)
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);
// Final atmosphere additive
@@ -170,13 +170,13 @@ void main()
// Increase ambient when there are more clouds
// TODO 9/20: DJH what does this do? max(0,(1-ambient)) will change the color
- vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+ vec3 ambient = ambient_color + max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)
+ vec3 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient);
// Attenuate cloud color by atmosphere
@@ -195,5 +195,5 @@ void main()
// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 1.0);
frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0);
- frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0); // 1.0 in norm.w masks off fog
+ frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS); // 1.0 in norm.w masks off fog
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 7700d16007..677c9c244c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -88,7 +88,7 @@ void main()
da = pow(da, light_gamma);
vec4 diffuse = texture2DRect(diffuseRect, tc);
- diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14025
+ diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
@@ -139,7 +139,7 @@ void main()
color = mix(color.rgb, reflected_color, envIntensity);
}
- if (norm.w < 0.5)
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
{
color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl
new file mode 100644
index 0000000000..96739d91d7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl
@@ -0,0 +1,192 @@
+/**
+ * @file class1/deferred/waterF.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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[4];
+#else
+#define frag_data gl_FragData
+#endif
+
+vec3 scaleSoftClip(vec3 inColor);
+vec3 atmosTransport(vec3 inColor);
+
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
+uniform sampler2D screenTex;
+uniform sampler2D refTex;
+uniform float sunAngle;
+uniform float sunAngle2;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform float refScale;
+uniform float kd;
+uniform vec2 screenRes;
+uniform vec3 normScale;
+uniform float fresnelScale;
+uniform float fresnelOffset;
+uniform float blurMultiplier;
+uniform vec2 screen_res;
+uniform mat4 norm_mat; //region space to screen space
+uniform int water_edge;
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+VARYING vec4 vary_position;
+
+vec2 encode_normal(vec3 n);
+vec3 scaleSoftClip(vec3 l);
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+ vec3 n = mix(bump1, bump2, blend_factor);
+ return n;
+}
+
+void main()
+{
+ vec4 color;
+ float dist = length(view.xyz);
+
+ //normalize view vector
+ vec3 viewVec = normalize(view.xyz);
+
+ //get wave normals
+ vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+
+
+ vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+ vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+ vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+ //get base fresnel components
+
+ vec3 df = vec3(
+ dot(viewVec, wave1),
+ dot(viewVec, (wave2 + wave3) * 0.5),
+ dot(viewVec, wave3)
+ ) * fresnelScale + fresnelOffset;
+ df *= df;
+
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+
+ float dist2 = dist;
+ dist = max(dist, 5.0);
+
+ float dmod = sqrt(dist);
+
+ vec2 dmod_scale = vec2(dmod*dmod, dmod);
+
+ //get reflected color
+ vec2 refdistort1 = wave1.xy*normScale.x;
+ vec2 refvec1 = distort+refdistort1/dmod_scale;
+ vec4 refcol1 = texture2D(refTex, refvec1);
+
+ vec2 refdistort2 = wave2.xy*normScale.y;
+ vec2 refvec2 = distort+refdistort2/dmod_scale;
+ vec4 refcol2 = texture2D(refTex, refvec2);
+
+ vec2 refdistort3 = wave3.xy*normScale.z;
+ vec2 refvec3 = distort+refdistort3/dmod_scale;
+ vec4 refcol3 = texture2D(refTex, refvec3);
+
+ vec4 refcol = refcol1 + refcol2 + refcol3;
+ float df1 = df.x + df.y + df.z;
+ refcol *= df1 * 0.333;
+
+ vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+ wavef.z *= max(-viewVec.z, 0.1);
+ wavef = normalize(wavef);
+
+ float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
+
+ vec2 refdistort4 = wavef.xy*0.125;
+ refdistort4.y -= abs(refdistort4.y);
+ 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);
+
+ //harden specular
+ spec = pow(spec, 128.0);
+
+ //figure out distortion vector (ripply)
+ vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
+
+ vec4 fb = texture2D(screenTex, distort2);
+
+ //mix with reflection
+ // 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.99999f);
+
+ vec4 pos = vary_position;
+
+ //color.rgb += spec * specular;
+
+ //color.rgb = atmosTransport(color.rgb);
+ //color.rgb = scaleSoftClip(color.rgb);
+
+ //color.rgb = refcol.rgb;
+ color.rgb = vec3(0.0);
+ color.a = spec * sunAngle2;
+
+ vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
+
+ //frag_data[0] = color;
+
+ // TODO: The non-obvious assignment below is copied from the pre-EEP WL shader code
+ // Unfortunately, fixing it causes a mismatch for EEP, and so it remains... for now
+ // SL-12975 (unfix pre-EEP broken alpha)
+ frag_data[0] = vec4(srgb_to_linear(color.rgb), 0.0);
+
+ frag_data[1] = vec4(1.0, 0.1, 0.0, 0.0); // occlusion, roughness, metalness
+ frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.0, GBUFFER_FLAG_HAS_PBR);// normalxy, env intens, flags (atmo kill)
+ //frag_data[3] = vec4(srgb_to_linear(refcol.rgb),0);
+ frag_data[3] = vec4(0, 0, 0, 0);
+
+
+ //frag_data[0] = vec4(0.0,0,0,0);
+ //frag_data[1] = vec4(0, 1.0, 0.0, 0.0);
+ //frag_data[3] = vec4(0);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
index c65cf48c67..d485379a56 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
@@ -22,20 +22,21 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-#extension GL_ARB_texture_rectangle : enable
-/*[EXTRA_CODE_HERE]*/
+//class2/environment/waterF.glsl
#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
+out vec4 frag_color;
#else
-#define frag_data gl_FragData
+#define frag_color gl_FragColor
#endif
-uniform sampler2D bumpMap;
+vec3 scaleSoftClip(vec3 inColor);
+vec3 atmosTransport(vec3 inColor);
+
+uniform sampler2D bumpMap;
uniform sampler2D bumpMap2;
-uniform float blend_factor;
+uniform float blend_factor;
uniform sampler2D screenTex;
uniform sampler2D refTex;
@@ -51,49 +52,45 @@ uniform vec3 normScale;
uniform float fresnelScale;
uniform float fresnelOffset;
uniform float blurMultiplier;
-uniform vec2 screen_res;
-uniform mat4 norm_mat; //region space to screen space
+
//bigWave is (refCoord.w, view.w);
VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
-VARYING vec4 vary_position;
-
-vec3 scaleSoftClip(vec3 c);
-vec2 encode_normal(vec3 n);
vec3 BlendNormal(vec3 bump1, vec3 bump2)
{
- //vec3 normal = bump1.xyz * vec3( 2.0, 2.0, 2.0) - vec3(1.0, 1.0, 0.0);
- //vec3 normal2 = bump2.xyz * vec3(-2.0, -2.0, 2.0) + vec3(1.0, 1.0, -1.0);
- //vec3 n = normalize(normal * dot(normal, normal2) - (normal2 * normal.z));
- vec3 n = normalize(mix(bump1, bump2, blend_factor));
+ vec3 n = mix(bump1, bump2, blend_factor);
return n;
}
+
void main()
{
vec4 color;
+
float dist = length(view.xy);
//normalize view vector
vec3 viewVec = normalize(view.xyz);
//get wave normals
- vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+ vec2 bigwave = vec2(refCoord.w, view.w);
+ vec3 wave1_a = texture2D(bumpMap, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
- vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+ vec3 wave1_b = texture2D(bumpMap2, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
vec3 wave1 = BlendNormal(wave1_a, wave1_b);
vec3 wave2 = BlendNormal(wave2_a, wave2_b);
vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
//get base fresnel components
vec3 df = vec3(
@@ -130,6 +127,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 = normalize(wavef);
@@ -140,7 +138,6 @@ 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
@@ -155,20 +152,19 @@ void main()
vec4 fb = texture2D(screenTex, distort2);
//mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
+ // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
-
- color.rgb *= 2.0f;
- color.rgb = scaleSoftClip(color.rgb);
+ color.rgb += spec * specular;
- vec4 pos = vary_position;
+ color.rgb = atmosTransport(color.rgb);
+ color.rgb = scaleSoftClip(color.rgb);
+ color.a = spec * sunAngle2;
- color.rgb += spec * specular;
- color.a = spec * sunAngle2;
-
- vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
+ frag_color = color;
+
+#if defined(WATER_EDGE)
+ gl_FragDepth = 0.9999847f;
+#endif
- frag_data[0] = vec4(color.rgb, color); // diffuse
- frag_data[1] = vec4(spec * specular, spec); // speccolor, spec
- frag_data[2] = vec4(encode_normal(wavef.xyz), 0.05, 0);// normalxy, 0, 0
}
+
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
index ee9c990b12..1463d507bc 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
@@ -29,8 +29,11 @@ vec3 scaleSoftClipFrag(vec3 light);
uniform int no_atmo;
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
-{
+{
if (no_atmo == 1)
{
return light;
@@ -40,6 +43,11 @@ vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
return light * 2.0;
}
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten)
+{
+ return atmosFragLighting(light, additive, atten);
+}
+
vec3 atmosLighting(vec3 light)
{
return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl
new file mode 100644
index 0000000000..c69eba93b6
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl
@@ -0,0 +1,251 @@
+/**
+ * @file class2\windlight\atmosphericsFuncs.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 sunlight_linear;
+uniform vec3 moonlight_color;
+uniform vec3 moonlight_linear;
+uniform int sun_up_factor;
+uniform vec3 ambient_color;
+uniform vec3 ambient_linear;
+uniform vec3 blue_horizon;
+uniform vec3 blue_horizon_linear;
+uniform vec3 blue_density;
+uniform vec3 blue_density_linear;
+uniform float haze_horizon;
+uniform float haze_density;
+uniform float haze_density_linear;
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+uniform vec3 glow;
+uniform float scene_light_strength;
+uniform mat3 ssao_effect_mat;
+uniform int no_atmo;
+uniform float sun_moon_glow_factor;
+
+float getAmbientClamp() { return 1.0f; }
+
+vec3 srgb_to_linear(vec3 col);
+
+// return colors in sRGB space
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+ out vec3 atten, bool use_ao)
+{
+ vec3 rel_pos = inPositionEye;
+
+ //(TERRAIN) limit altitude
+ if (abs(rel_pos.y) > max_y) rel_pos *= (max_y / rel_pos.y);
+
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+
+ // sunlight attenuation effect (hue and brightness) due to atmosphere
+ // this is used later for sunlight modulation at various altitudes
+ vec3 light_atten = (blue_density + vec3(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
+
+ vec3 combined_haze = blue_density + vec3(haze_density);
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = vec3(haze_density) / combined_haze;
+
+ //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain)
+ float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y);
+ sunlight *= exp(-light_atten * above_horizon_factor); // for sun [horizon..overhead] this maps to an exp curve [0..1]
+
+ // main atmospheric scattering line integral
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist*distance_multiplier in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist * distance_multiplier);
+
+ // final atmosphere attenuation factor
+ atten = combined_haze.rgb;
+
+ // compute haze glow
+ float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
+
+ // dampen sun additive contrib when not facing it...
+ // SL-13539: This "if" clause causes an "additive" white artifact at roughly 77 degreees.
+ // if (length(light_dir) > 0.01)
+ haze_glow *= max(0.0f, dot(light_dir, rel_pos_norm));
+
+ haze_glow = 1. - haze_glow;
+ // haze_glow is 0 at the sun and increases away from sun
+ haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ haze_glow *= glow.x;
+ // higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ haze_glow = pow(haze_glow, glow.z);
+ // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ // add "minimum anti-solar illumination"
+ haze_glow += .25;
+
+ haze_glow *= sun_moon_glow_factor;
+
+ vec3 amb_color = ambient_color;
+
+ // increase ambient when there are more clouds
+ vec3 tmpAmbient = amb_color + (vec3(1.) - amb_color) * 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);
+ */
+ if (use_ao)
+ {
+ tmpAmbient = mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor);
+ }
+
+ // Similar/Shared Algorithms:
+ // indra\llinventory\llsettingssky.cpp -- LLSettingsSky::calculateLightSettings()
+ // indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars()
+ // haze color
+ vec3 cs = sunlight.rgb * (1. - cloud_shadow);
+ additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
+
+ // brightness of surface both sunlight and ambient
+ sunlit = sunlight.rgb;
+ amblit = tmpAmbient.rgb;
+ additive *= vec3(1.0 - combined_haze);
+}
+
+
+vec3 srgb_to_linear(vec3 col);
+
+// provide a touch of lighting in the opposite direction of the sun light
+ // so areas in shadow don't lose all detail
+float ambientLighting(vec3 norm, vec3 light_dir)
+{
+ float ambient = min(abs(dot(norm.xyz, light_dir.xyz)), 1.0);
+ ambient *= 0.56;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
+ return ambient;
+}
+
+
+// return colors in linear space
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+ out vec3 atten)
+{
+#if 1
+ calcAtmosphericVars(inPositionEye, light_dir, 1.0, sunlit, amblit, additive, atten, false);
+ sunlit = srgb_to_linear(sunlit);
+ additive = srgb_to_linear(additive);
+ amblit = ambient_linear;
+
+ amblit *= ambientLighting(norm, light_dir);
+#else
+
+ //EXPERIMENTAL -- attempt to factor out srgb_to_linear conversions above
+ vec3 rel_pos = inPositionEye;
+
+ //(TERRAIN) limit altitude
+ if (abs(rel_pos.y) > max_y) rel_pos *= (max_y / rel_pos.y);
+
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
+ vec3 sunlight = (sun_up_factor == 1) ? vec3(sunlight_linear, 0.0) : vec3(moonlight_linear, 0.0);
+
+ // sunlight attenuation effect (hue and brightness) due to atmosphere
+ // this is used later for sunlight modulation at various altitudes
+ vec3 light_atten = (blue_density + vec3(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
+
+ vec3 combined_haze = blue_density + vec3(haze_density);
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = vec3(haze_density) / combined_haze;
+
+ //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain)
+ float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y);
+ sunlight *= exp(-light_atten * above_horizon_factor); // for sun [horizon..overhead] this maps to an exp curve [0..1]
+
+ // main atmospheric scattering line integral
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist*distance_multiplier in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist * distance_multiplier);
+
+ // final atmosphere attenuation factor
+ atten = combined_haze.rgb;
+
+ // compute haze glow
+ float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
+
+ // dampen sun additive contrib when not facing it...
+ // SL-13539: This "if" clause causes an "additive" white artifact at roughly 77 degreees.
+ // if (length(light_dir) > 0.01)
+ haze_glow *= max(0.0f, dot(light_dir, rel_pos_norm));
+
+ haze_glow = 1. - haze_glow;
+ // haze_glow is 0 at the sun and increases away from sun
+ haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ haze_glow *= glow.x;
+ // higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ haze_glow = pow(haze_glow, glow.z);
+ // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ // add "minimum anti-solar illumination"
+ haze_glow += .25;
+
+ haze_glow *= sun_moon_glow_factor;
+
+ //vec3 amb_color = vec4(ambient_linear, 0.0);
+ vec3 amb_color = ambient_color;
+
+ // increase ambient when there are more clouds
+ vec3 tmpAmbient = amb_color + (vec3(1.) - amb_color) * cloud_shadow * 0.5;
+
+ // Similar/Shared Algorithms:
+ // indra\llinventory\llsettingssky.cpp -- LLSettingsSky::calculateLightSettings()
+ // indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars()
+ // haze color
+ vec3 cs = sunlight.rgb * (1. - cloud_shadow);
+ additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
+
+ // brightness of surface both sunlight and ambient
+ sunlit = min(sunlight.rgb, vec3(1));
+ amblit = tmpAmbient.rgb;
+ additive *= vec3(1.0 - combined_haze);
+
+ //sunlit = sunlight_linear;
+ amblit = ambient_linear*0.8;
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index fa928d993e..9c5a4903d0 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -35,15 +35,15 @@ out vec4 frag_color;
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec3 vary_CloudColorSun;
+VARYING vec3 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
uniform sampler2D cloud_noise_texture;
uniform sampler2D cloud_noise_texture_next;
uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
+uniform vec3 cloud_pos_density1;
+uniform vec3 cloud_pos_density2;
uniform float cloud_scale;
uniform float cloud_variance;
@@ -70,8 +70,8 @@ void main()
vec2 uv1 = vary_texcoord0.xy;
vec2 uv2 = vary_texcoord1.xy;
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ vec3 cloudColorSun = vary_CloudColorSun;
+ vec3 cloudColorAmbient = vary_CloudColorAmbient;
float cloudDensity = vary_CloudDensity;
vec2 uv3 = vary_texcoord2.xy;
vec2 uv4 = vary_texcoord3.xy;
@@ -120,7 +120,7 @@ void main()
alpha2 = 1. - alpha2 * alpha2;
// Combine
- vec4 color;
+ vec3 color;
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
color.rgb *= 2.;
color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index 97ffa9feef..650009d393 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
@@ -33,8 +33,8 @@ ATTRIBUTE vec2 texcoord0;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec3 vary_CloudColorSun;
+VARYING vec3 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
VARYING vec2 vary_texcoord0;
@@ -46,13 +46,13 @@ VARYING float altitude_blend_factor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -60,10 +60,10 @@ uniform float cloud_shadow;
uniform float density_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
+uniform vec3 cloud_color;
uniform float cloud_scale;
@@ -114,17 +114,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
+ vec3 sunlight = sunlight_color;
+ vec3 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);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -155,14 +155,14 @@ void main()
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
+ vec3 tmpAmbient = ambient_color;
tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= (1. - cloud_shadow);
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// CLOUDS
@@ -178,7 +178,7 @@ void main()
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
vary_CloudColorSun *= combined_haze;
vary_CloudColorAmbient *= combined_haze;
- vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
+ vec3 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
// Make a nice cloud density based on the cloud_shadow value that was passed in.
vary_CloudDensity = 2. * (cloud_shadow - 0.25);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
index 68db7fcbb1..a32a572461 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
@@ -28,6 +28,21 @@ uniform int no_atmo;
vec3 getAtmosAttenuation();
vec3 getAdditiveColor();
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
+vec3 scaleSoftClipFragLinear(vec3 light)
+{ // identical to non-linear version and that's probably close enough
+ if (no_atmo == 1)
+ {
+ return light;
+ }
+ //soft clip effect:
+ light = 1. - clamp(light, vec3(0.), vec3(1.));
+ light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side
+ return light;
+}
+
vec3 scaleSoftClipFrag(vec3 light)
{
if (no_atmo == 1)
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
index 7146349453..7a229e0f5e 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
@@ -33,7 +33,7 @@ out vec4 frag_color;
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_HazeColor;
+VARYING vec3 vary_HazeColor;
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light);
@@ -45,7 +45,7 @@ void main()
// the fragment) if the sky wouldn't show up because the clouds
// are fully opaque.
- vec4 color;
+ vec3 color;
color = vary_HazeColor;
color.rgb *= 2.;
/// Gamma correct for WL (soft clip effect).
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
index a0a33b8642..8f7726bb0b 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
@@ -32,18 +32,18 @@ ATTRIBUTE vec3 position;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_HazeColor;
+VARYING vec3 vary_HazeColor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -52,11 +52,9 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
-
void main()
{
// World / view / projection
@@ -83,17 +81,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
- vec4 light_atten;
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec3 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);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -121,21 +119,21 @@ void main()
// For sun, add to glow. For moon, remove glow entirely. SL-13768
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
- vec4 color =
+ vec3 color =
(blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
- tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+ vec3 tmpAmbient = ambient_color;
+ tmpAmbient += max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// Attenuate cloud color by atmosphere
diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
index b53a2e237f..ecf0430a88 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
@@ -32,6 +32,9 @@ vec3 getAtmosAttenuation();
uniform int no_atmo;
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
{
light *= atten.r;
@@ -44,6 +47,13 @@ vec3 atmosTransport(vec3 light)
return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
}
+vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten)
+{
+ // same as non-linear version, probably fine
+ float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
+ return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
+}
+
vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
{
float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
deleted file mode 100644
index df9704ec25..0000000000
--- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * @file avatarV.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 mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec4 clothing;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-mat4 getSkinnedTransform();
-void calcAtmospherics(vec3 inPositionEye);
-
-uniform vec4 color;
-
-uniform vec4 gWindDir;
-uniform vec4 gSinWaveParams;
-uniform vec4 gGravity;
-
-const vec4 gMinMaxConstants = vec4(1.0, 0.166666, 0.0083143, .00018542); // #minimax-generated coefficients
-const vec4 gPiConstants = vec4(0.159154943, 6.28318530, 3.141592653, 1.5707963); // # {1/2PI, 2PI, PI, PI/2}
-
-void main()
-{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- mat4 trans = getSkinnedTransform();
-
- vec3 norm;
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- //wind
- vec4 windEffect;
- windEffect = vec4(dot(norm, gWindDir.xyz));
- pos.x = dot(trans[2].xyz, position.xyz);
- windEffect.xyz = pos.x * vec3(0.015, 0.015, 0.015)
- + windEffect.xyz;
- windEffect.w = windEffect.w * 2.0 + 1.0; // move wind offset value to [-1, 3]
- windEffect.w = windEffect.w*gWindDir.w; // modulate wind strength
-
- windEffect.xyz = windEffect.xyz*gSinWaveParams.xyz
- +vec3(gSinWaveParams.w); // use sin wave params to scale and offset input
-
-
- //reduce to period of 2 PI
- vec4 temp1, temp0, temp2, offsetPos;
- temp1.xyz = windEffect.xyz * gPiConstants.x; // change input as multiple of [0-2PI] to [0-1]
- temp0.y = mod(temp1.x,1.0);
- windEffect.x = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
- temp1.z = temp1.z - gPiConstants.w; // shift normal oscillation by PI/2
- temp0.y = mod(temp1.z,1.0);
-
- windEffect.z = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
- windEffect.xyz = windEffect.xyz + vec3(-3.141592); // offset to [-PI, PI]
-
-
- //calculate sinusoid
- vec4 sinWave;
- temp1 = windEffect*windEffect;
- sinWave = -temp1 * gMinMaxConstants.w
- + vec4(gMinMaxConstants.z); // y = -(x^2)/7! + 1/5!
- sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.y); // y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3!
- sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.x); // y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1
- sinWave = sinWave * windEffect; // y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1)
-
- // sinWave.x holds sin(norm . wind_direction) with primary frequency
- // sinWave.y holds sin(norm . wind_direction) with secondary frequency
- // sinWave.z hold cos(norm . wind_direction) with primary frequency
- sinWave.xyz = sinWave.xyz * gWindDir.w
- + vec3(windEffect.w); // multiply by wind strength in gWindDir.w [-wind, wind]
-
- // add normal facing bias offset [-wind,wind] -> [-wind - .25, wind + 1]
- temp1 = vec4(dot(norm, gGravity.xyz)); // how much is this normal facing in direction of gGravity?
- temp1 = min(temp1, vec4(0.2,0.0,0.0,0.0)); // clamp [-1, 1] to [-1, 0.2]
- temp1 = temp1*vec4(1.5,0.0,0.0,0.0); // scale from [-1,0.2] to [-1.5, 0.3]
- sinWave.x = sinWave.x + temp1.x; // add gGravity effect to sinwave (only primary frequency)
- sinWave.xyz = sinWave.xyz * clothing.w; // modulate by clothing coverage
-
- sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0)); // clamp to underlying body shape
- offsetPos = clothing * sinWave.x; // multiply wind effect times clothing displacement
- temp2 = gWindDir*sinWave.z + vec4(norm,0); // calculate normal offset due to wind oscillation
- offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+vec4(position.xyz, 1.0); // add to offset vertex position, and zero out effect from w
- norm += temp2.xyz*2.0; // add sin wave effect on normals (exaggerated)
-
- //add "backlighting" effect
- float colorAcc;
- colorAcc = 1.0 - clothing.w;
- norm.z -= colorAcc * 0.2;
-
- //renormalize normal (again)
- norm = normalize(norm);
-
- pos.x = dot(trans[0], offsetPos);
- pos.y = dot(trans[1], offsetPos);
- pos.z = dot(trans[2], offsetPos);
- pos.w = 1.0;
-
- calcAtmospherics(pos.xyz);
-
- vec4 col = calcLighting(pos.xyz, norm, color);
- vertex_color = col;
-
- gl_Position = projection_matrix * pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
deleted file mode 100644
index d973326f93..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file avatarShadowF.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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- frag_color = computeMoments(length(pos), 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
deleted file mode 100644
index 1a655e6467..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file attachmentShadowV.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 mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-uniform mat4 texture_matrix0;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getObjectSkinnedTransform();
-
-VARYING vec4 pos;
-
-void main()
-{
- //transform vertex
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- pos = (mat*vec4(position.xyz, 1.0));
- pos = projection_matrix * vec4(pos.xyz, 1.0);
-
-#if !defined(DEPTH_CLAMP)
- pos.z = max(pos.z, -pos.w+0.01);
-#endif
- gl_Position = pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
deleted file mode 100644
index 48eefc7a73..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * @file avatarShadowF.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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-VARYING vec4 pos;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- frag_color = computeMoments(length(pos), 1.0);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
deleted file mode 100644
index 164b355f20..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file avatarShadowV.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 mat4 projection_matrix;
-
-mat4 getSkinnedTransform();
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-VARYING vec4 pos;
-
-void main()
-{
- vec3 norm;
-
- vec4 pos_in = vec4(position.xyz, 1.0);
- mat4 trans = getSkinnedTransform();
-
- 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);
-
- pos = projection_matrix * pos;
-
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
-}
-
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
deleted file mode 100644
index 32210f60dc..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-vec4 computeMoments(float depth, float alpha);
-
-void main()
-{
- if (cloud_scale >= 0.001)
- {
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = computeMoments(length(pos), alpha1);
- }
- else
- {
- frag_color = vec4(0);
- }
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
deleted file mode 100644
index effb070f93..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
deleted file mode 100644
index e40d7e7c75..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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
-
-/////////////////////////////////////////////////////////////////////////
-// The fragment shader for the sky
-/////////////////////////////////////////////////////////////////////////
-
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING vec3 vary_pos;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return cloud_noise_sample;
-}
-
-void main()
-{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- if (cloud_scale < 0.001)
- {
- discard;
- }
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 16.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- vec3 view_ray = vary_pos.xyz + camPosLocal;
-
- vec3 view_direction = normalize(view_ray);
- vec3 sun_direction = normalize(sun_dir);
- vec3 earth_center = vec3(0, 0, -6360.0f);
- vec3 camPos = (camPosLocal / 1000.0f) - earth_center;
-
- vec3 transmittance;
- vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 1.0 - alpha1, sun_direction, transmittance);
-
- vec3 sun_color = vec3(1.0) - exp(-radiance_sun * 0.0001);
-
- // Combine
- vec4 color;
-
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
-
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
-
- vec3 sun_indir = vec3(-view_direction.xy, view_direction.z);
- vec3 amb = vec3(dot(l1r, l1tap * vec4(1, sun_indir)),
- dot(l1g, l1tap * vec4(1, sun_indir)),
- dot(l1b, l1tap * vec4(1, sun_indir)));
-
-
- amb = max(vec3(0), amb);
-
- color.rgb = sun_color * cloud_color.rgb * (1. - alpha2);
- color.rgb = pow(color.rgb, vec3(1.0 / 2.2));
- color.rgb += amb;
-
- frag_data[0] = vec4(color.rgb, alpha1);
- frag_data[1] = vec4(0);
- frag_data[2] = vec4(0,1,0,1);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
deleted file mode 100644
index 71e422ddf0..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file WLCloudsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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 mat4 modelview_projection_matrix;
-uniform mat4 modelview_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-//////////////////////////////////////////////////////////////////////////
-// The vertex shader for creating the atmospheric sky
-///////////////////////////////////////////////////////////////////////////////
-
-// Output parameters
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING vec3 vary_pos;
-
-// Inputs
-uniform float cloud_scale;
-uniform vec4 lightnorm;
-uniform vec3 camPosLocal;
-
-void main()
-{
- vary_pos = position;
-
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // Texture coords
- vary_texcoord0 = texcoord0;
- vary_texcoord0.xy -= 0.5;
- vary_texcoord0.xy /= max(0.001, cloud_scale);
- vary_texcoord0.xy += 0.5;
-
- vary_texcoord1 = vary_texcoord0;
- vary_texcoord1.x += lightnorm.x * 0.0125;
- vary_texcoord1.y += lightnorm.z * 0.0125;
-
- vary_texcoord2 = vary_texcoord0 * 16.;
- vary_texcoord3 = vary_texcoord1 * 16.;
-
- // END CLOUDS
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
deleted file mode 100644
index e27bbce094..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file class1/deferred/deferredUtil.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 sampler2DRect normalMap;
-uniform sampler2DRect depthMap;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec2 getScreenCoordinate(vec2 screenpos)
-{
- vec2 sc = screenpos.xy * 2.0;
- if (screen_res.x > 0 && screen_res.y > 0)
- {
- sc /= screen_res;
- }
- return sc - vec2(1.0, 1.0);
-}
-
-vec3 getNorm(vec2 screenpos)
-{
- vec2 enc = texture2DRect(normalMap, screenpos.xy).xy;
- 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;
-}
-
-float getDepth(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen).r;
- return depth;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = getDepth(pos_screen);
- vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec4 getPositionWithDepth(vec2 pos_screen, float depth)
-{
- vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
deleted file mode 100644
index cdaff4b09f..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * @file depthToShadowVolumeG.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-#extension GL_ARB_geometry_shader4 : enable
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-layout (triangles) in;
-layout (triangle_strip, max_vertices = 128) out;
-
-uniform sampler2DRect depthMap;
-uniform mat4 shadowMatrix[6];
-uniform vec4 lightpos;
-
-VARYING vec2 vary_texcoord0;
-
-out vec3 to_vec;
-
-void cross_products(out vec4 ns[3], int a, int b, int c)
-{
- ns[0] = cross(gl_PositionIn[b].xyz - gl_PositionIn[a].xyz, gl_PositionIn[c].xyz - gl_PositionIn[a].xyz);
- ns[1] = cross(gl_PositionIn[c].xyz - gl_PositionIn[b].xyz, gl_PositionIn[a].xyz - gl_PositionIn[b].xyz);
- ns[2] = cross(gl_PositionIn[a].xyz - gl_PositionIn[c].xyz, gl_PositionIn[b].xyz - gl_PositionIn[c].xyz);
-}
-
-vec3 getLightDirection(vec4 lightpos, vec3 pos)
-{
-
- vec3 lightdir = lightpos.xyz - lightpos.w * pos;
- return lightdir;
-}
-
-void emitTri(vec4 v[3])
-{
- gl_Position = proj_matrix * v[0];
- EmitVertex();
-
- gl_Position = proj_matrix * v[1];
- EmitVertex();
-
- gl_Position = proj_matrix * v[2];
- EmitVertex();
-
- EndPrimitive();
-}
-
-void emitQuad(vec4 v[4]
-{
- // Emit a quad as a triangle strip.
- gl_Position = proj_matrix*v[0];
- EmitVertex();
-
- gl_Position = proj_matrix*v[1];
- EmitVertex();
-
- gl_Position = proj_matrix*v[2];
- EmitVertex();
-
- gl_Position = proj_matrix*v[3];
- EmitVertex();
-
- EndPrimitive();
-}
-
-void emitPrimitives(int layer)
-{
- int i = layer;
- gl_Layer = i;
-
- vec4 depth1 = vec4(texture2DRect(depthMap, tc0).rg, texture2DRect(depthMap, tc1).rg));
- vec3 depth2 = vec4(texture2DRect(depthMap, tc2).rg, texture2DRect(depthMap, tc3).rg));
- vec3 depth3 = vec4(texture2DRect(depthMap, tc4).rg, texture2DRect(depthMap, tc5).rg));
- vec3 depth4 = vec4(texture2DRect(depthMap, tc6).rg, texture2DRect(depthMap, tc7).rg));
-
- depth1 = min(depth1, depth2);
- depth1 = min(depth1, depth3);
- depth1 = min(depth1, depth4);
-
- vec2 depth = min(depth1.xy, depth1.zw);
-
- int side = sqrt(gl_VerticesIn);
-
- for (int j = 0; j < side; j++)
- {
- for (int k = 0; k < side; ++k)
- {
- vec3 pos = gl_PositionIn[(j * side) + k].xyz;
- vec4 v = shadowMatrix[i] * vec4(pos, 1.0);
- gl_Position = v;
- to_vec = pos - light_position.xyz * depth;
- EmitVertex();
- }
-
- EndPrimitive();
- }
-
- vec3 norms[3]; // Normals
- vec3 lightdir3]; // Directions toward light
-
- vec4 v[4]; // Temporary vertices
-
- vec4 or_pos[3] =
- { // Triangle oriented toward light source
- gl_PositionIn[0],
- gl_PositionIn[2],
- gl_PositionIn[4]
- };
-
- // Compute normal at each vertex.
- cross_products(n, 0, 2, 4);
-
- // Compute direction from vertices to light.
- lightdir[0] = getLightDirection(lightpos, gl_PositionIn[0].xyz);
- lightdir[1] = getLightDirection(lightpos, gl_PositionIn[2].xyz);
- lightdir[2] = getLightDirection(lightpos, gl_PositionIn[4].xyz);
-
- // Check if the main triangle faces the light.
- bool faces_light = true;
- if (!(dot(ns[0],d[0]) > 0
- |dot(ns[1],d[1]) > 0
- |dot(ns[2],d[2]) > 0))
- {
- // Flip vertex winding order in or_pos.
- or_pos[1] = gl_PositionIn[4];
- or_pos[2] = gl_PositionIn[2];
- faces_light = false;
- }
-
- // Near cap: simply render triangle.
- emitTri(or_pos);
-
- // Far cap: extrude positions to infinity.
- v[0] =vec4(lightpos.w * or_pos[0].xyz - lightpos.xyz,0);
- v[1] =vec4(lightpos.w * or_pos[2].xyz - lightpos.xyz,0);
- v[2] =vec4(lightpos.w * or_pos[1].xyz - lightpos.xyz,0);
-
- emitTri(v);
-
- // Loop over all edges and extrude if needed.
- for ( int i=0; i<3; i++ )
- {
- // Compute indices of neighbor triangle.
- int v0 = i*2;
- int nb = (i*2+1);
- int v1 = (i*2+2) % 6;
- cross_products(n, v0, nb, v1);
-
- // Compute direction to light, again as above.
- d[0] =lightpos.xyz-lightpos.w*gl_PositionIn[v0].xyz;
- d[1] =lightpos.xyz-lightpos.w*gl_PositionIn[nb].xyz;
- d[2] =lightpos.xyz-lightpos.w*gl_PositionIn[v1].xyz;
-
- bool is_parallel = gl_PositionIn[nb].w < 1e-5;
-
- // Extrude the edge if it does not have a
- // neighbor, or if it's a possible silhouette.
- if (is_parallel ||
- ( faces_light != (dot(ns[0],d[0])>0 ||
- dot(ns[1],d[1])>0 ||
- dot(ns[2],d[2])>0) ))
- {
- // Make sure sides are oriented correctly.
- int i0 = faces_light ? v0 : v1;
- int i1 = faces_light ? v1 : v0;
-
- v[0] = gl_PositionIn[i0];
- v[1] = vec4(lightpos.w*gl_PositionIn[i0].xyz - lightpos.xyz, 0);
- v[2] = gl_PositionIn[i1];
- v[3] = vec4(lightpos.w*gl_PositionIn[i1].xyz - lightpos.xyz, 0);
-
- emitQuad(v);
- }
- }
-}
-
-void main()
-{
- // Output
- emitPrimitives(0);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
new file mode 100644
index 0000000000..c0a1491446
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -0,0 +1,106 @@
+/**
+ * @file fullbrightShinyF.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$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#ifndef HAS_DIFFUSE_LOOKUP
+uniform sampler2D diffuseMap;
+#endif
+
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
+VARYING vec3 vary_position;
+
+uniform samplerCube environmentMap;
+
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
+uniform int no_atmo;
+
+vec3 fullbrightShinyAtmosTransport(vec3 light);
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
+
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+// reflection probe interface
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
+
+// See:
+// class1\deferred\fullbrightShinyF.glsl
+// class1\lighting\lightFullbrightShinyF.glsl
+void main()
+{
+#ifdef HAS_DIFFUSE_LOOKUP
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+#else
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+#endif
+
+ color.rgb *= vertex_color.rgb;
+
+ // SL-9632 HUDs are affected by Atmosphere
+ if (no_atmo == 0)
+ {
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ vec3 pos = vary_position;
+ calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
+
+ float env_intensity = vertex_color.a;
+
+ vec3 ambenv;
+ vec3 glossenv;
+ vec3 legacyenv;
+ vec3 norm = normalize(vary_texcoord1.xyz);
+ vec4 spec = vec4(0,0,0,0);
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, env_intensity);
+ applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity);
+
+ color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
+ color.rgb = fullbrightScaleSoftClip(color.rgb);
+ }
+
+ color.a = 1.0;
+
+ color.rgb = srgb_to_linear(color.rgb);
+ frag_color = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
deleted file mode 100644
index 34d26cddea..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file class3/deferred/gatherSkyShF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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
-
-VARYING vec2 vary_frag;
-
-uniform vec2 screen_res;
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-void main()
-{
- vec2 offset = vec2(2.0) / screen_res;
-
- vec4 r = vec4(0);
- vec4 g = vec4(0);
- vec4 b = vec4(0);
-
- vec2 tc = vary_frag * 2.0;
-
- r += texture2D(sh_input_r, tc + vec2(0, 0));
- r += texture2D(sh_input_r, tc + vec2(offset.x, 0));
- r += texture2D(sh_input_r, tc + vec2(0, offset.y));
- r += texture2D(sh_input_r, tc + vec2(offset.x, offset.y));
- r /= 4.0f;
-
- g += texture2D(sh_input_g, tc + vec2(0, 0));
- g += texture2D(sh_input_g, tc + vec2(offset.x, 0));
- g += texture2D(sh_input_g, tc + vec2(0, offset.y));
- g += texture2D(sh_input_g, tc + vec2(offset.x, offset.y));
- g /= 4.0f;
-
- b += texture2D(sh_input_b, tc + vec2(0, 0));
- b += texture2D(sh_input_b, tc + vec2(offset.x, 0));
- b += texture2D(sh_input_b, tc + vec2(0, offset.y));
- b += texture2D(sh_input_b, tc + vec2(offset.x, offset.y));
- b /= 4.0f;
-
- frag_data[0] = r;
- frag_data[1] = g;
- frag_data[2] = b;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
deleted file mode 100644
index 337c8a50fe..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file gatherSkyShV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 vary_frag;
-uniform vec2 screen_res;
-
-void main()
-{
- // pass through untransformed fullscreen pos
- float oo_divisor = screen_res.x / 64.0;
- vec3 pos = (position.xyz * oo_divisor) + vec3(oo_divisor - 1, oo_divisor - 1, 0);
- gl_Position = vec4(pos.xyz, 1.0);
- vary_frag = texcoord0 * oo_divisor;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
deleted file mode 100644
index d5d91c88f0..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * @file class3/deferred/genSkyShF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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
-
-VARYING vec2 vary_frag;
-
-uniform vec3 sun_dir;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-
-vec3 calcDirection(vec2 tc)
-{
- float phi = tc.y * 2.0 * 3.14159265;
- float cosTheta = sqrt(1.0 - tc.x);
- float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
- return vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
-}
-
-// reverse mapping above to convert a hemisphere direction into phi/theta values
-void getPhiAndThetaFromDirection(vec3 dir, out float phi, out float theta)
-{
- float sin_theta;
- float cos_theta;
- cos_theta = dir.z;
- theta = acos(cos_theta);
- sin_theta = sin(theta);
- phi = abs(sin_theta) > 0.0001 ? acos(dir.x / sin_theta) : 1.0;
-}
-
-// reverse mapping above to convert a hemisphere direction into an SH texture sample pos
-vec2 calcShUvFromDirection(vec3 dir)
-{
- vec2 uv;
- float phi;
- float theta;
- getPhiAndThetaFromDirection(dir, phi, theta);
- uv.y = phi / 2.0 * 3.14159265;
- uv.x = theta / 2.0 * 3.14159265;
- return uv;
-}
-
-void projectToL1(vec3 n, vec3 c, vec4 basis, out vec4 coeffs[3])
-{
- coeffs[0] = vec4(basis.x, n * basis.yzw * c.r);
- coeffs[1] = vec4(basis.x, n * basis.yzw * c.g);
- coeffs[2] = vec4(basis.x, n * basis.yzw * c.b);
-}
-
-void main()
-{
- float Y00 = sqrt(1.0 / 3.14159265) * 0.5;
- float Y1x = sqrt(3.0 / 3.14159265) * 0.5;
- float Y1y = Y1x;
- float Y1z = Y1x;
-
- vec4 L1 = vec4(Y00, Y1x, Y1y, Y1z);
-
- vec3 view_direction = calcDirection(vary_frag);
- vec3 sun_direction = normalize(sun_dir);
- vec3 cam_pos = vec3(0, 0, 6360);
-
- vec3 transmittance;
- vec3 radiance = GetSkyLuminance(cam_pos, view_direction, 0.0f, sun_direction, transmittance);
-
- vec3 color = vec3(1.0) - exp(-radiance * 0.0001);
-
- color = pow(color, vec3(1.0/2.2));
-
- vec4 coeffs[3];
- coeffs[0] = vec4(0);
- coeffs[1] = vec4(0);
- coeffs[2] = vec4(0);
-
- projectToL1(view_direction, color.rgb, L1, coeffs);
-
- frag_data[0] = coeffs[0];
- frag_data[1] = coeffs[1];
- frag_data[2] = coeffs[2];
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
deleted file mode 100644
index 33c5667cae..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file class3/deferred/indirect.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-vec3 GetIndirect(vec3 norm)
-{
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
- vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
- dot(l1g, l1tap * vec4(1, norm.xyz)),
- dot(l1b, l1tap * vec4(1, norm.xyz)));
- indirect = clamp(indirect, vec3(0), vec3(1.0));
- return indirect;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
new file mode 100644
index 0000000000..8016022d78
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -0,0 +1,380 @@
+/**
+* @file materialF.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$
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+//class1/deferred/materialF.glsl
+
+// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
+
+#define DIFFUSE_ALPHA_MODE_NONE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 otherwise
+uniform int sun_up_factor;
+
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
+#endif
+
+vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFragLinear(vec3 l);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten);
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cs);
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#ifdef HAS_SUN_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
+
+uniform samplerCube environmentMap;
+uniform sampler2D lightFunc;
+
+// Inputs
+uniform vec4 morphFactor;
+uniform vec3 camPosLocal;
+uniform mat3 env_mat;
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+VARYING vec2 vary_fragcoord;
+
+VARYING vec3 vary_position;
+
+uniform mat4 proj_mat;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec4 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+float getAmbientClamp();
+void waterClip(vec3 pos);
+
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
+{
+ // SL-14895 inverted attenuation work-around
+ // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
+ // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
+ // to recover the `adjusted_radius` value previously being sent as la.
+ float falloff_factor = (12.0 * fa) - 9.0;
+ float inverted_la = falloff_factor / la;
+ // Yes, it makes me want to cry as well. DJH
+
+ vec3 col = vec3(0);
+
+ //get light vector
+ vec3 lv = lp.xyz - v;
+
+ //get distance
+ float dist = length(lv);
+ float da = 1.0;
+
+ dist /= inverted_la;
+
+ if (dist > 0.0 && inverted_la > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0f;
+
+ if (dist_atten <= 0.0)
+ {
+ return col;
+ }
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= dot(n, lv);
+
+ float lit = 0.0f;
+
+ float amb_da = ambiance;
+ if (da >= 0)
+ {
+ lit = max(da * dist_atten, 0.0);
+ col = lit * light_col * diffuse;
+ amb_da += (da*0.5 + 0.5) * ambiance;
+ }
+ amb_da += (da*da*0.5 + 0.5) * ambiance;
+ amb_da *= dist_atten;
+ amb_da = min(amb_da, 1.0f - lit);
+
+ // SL-10969 need to see why these are blown out
+ //col.rgb += amb_da * light_col * diffuse;
+
+ if (spec.a > 0.0)
+ {
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv + npos);
+ float nh = dot(n, h);
+ float nv = dot(n, 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);
+ vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ col += speccol;
+ }
+ }
+ }
+
+ return max(col, vec3(0.0, 0.0, 0.0));
+}
+
+#else
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+#endif
+
+uniform sampler2D diffuseMap; //always in sRGB space
+
+#ifdef HAS_NORMAL_MAP
+uniform sampler2D bumpMap;
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+uniform sampler2D specularMap;
+
+VARYING vec2 vary_texcoord2;
+#endif
+
+uniform float env_intensity;
+uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+uniform float minimum_alpha;
+#endif
+
+#ifdef HAS_NORMAL_MAP
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+VARYING vec2 vary_texcoord1;
+#else
+VARYING vec3 vary_normal;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+vec2 encode_normal(vec3 n);
+
+void main()
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ waterClip(vary_position.xyz);
+#endif
+
+ vec2 pos_screen = vary_texcoord0.xy;
+
+ vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
+ diffcol.rgb *= vertex_color.rgb;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+
+ // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
+ float bias = 0.001953125; // 1/512, or half an 8-bit quantization
+ if (diffcol.a < minimum_alpha-bias)
+ {
+ discard;
+ }
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+ vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
+ spec.rgb *= specular_color.rgb;
+#else
+ vec4 spec = vec4(specular_color.rgb, 1.0);
+#endif
+
+#ifdef HAS_NORMAL_MAP
+ vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
+
+ norm.xyz = norm.xyz * 2 - 1;
+
+ vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
+ dot(norm.xyz,vary_mat1),
+ dot(norm.xyz,vary_mat2));
+#else
+ vec4 norm = vec4(0,0,0,1.0);
+ vec3 tnorm = vary_normal;
+#endif
+
+ norm.xyz = normalize(tnorm.xyz);
+
+ vec2 abnormal = encode_normal(norm.xyz);
+
+ vec4 final_color = diffcol;
+
+#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
+ final_color.a = emissive_brightness;
+#else
+ final_color.a = max(final_color.a, emissive_brightness);
+#endif
+
+ vec4 final_specular = spec;
+
+#ifdef HAS_SPECULAR_MAP
+ vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, GBUFFER_FLAG_HAS_ATMOS);
+ final_specular.a = specular_color.a * norm.a;
+#else
+ vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, GBUFFER_FLAG_HAS_ATMOS);
+ final_specular.a = specular_color.a;
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ //forward rendering, output lit linear color
+ diffcol.rgb = srgb_to_linear(diffcol.rgb);
+ final_specular.rgb = srgb_to_linear(final_specular.rgb);
+
+ vec3 pos = vary_position;
+
+ float shadow = 1.0f;
+
+#ifdef HAS_SUN_SHADOW
+ shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
+#endif
+
+ vec4 diffuse = final_color;
+
+ vec3 color = vec3(0,0,0);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+
+ float bloom = 0.0;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
+
+ vec3 ambenv;
+ vec3 glossenv;
+ vec3 legacyenv;
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, final_specular.a, env_intensity);
+
+ // use sky settings ambient or irradiance map sample, whichever is brighter
+ color = max(amblit, ambenv);
+
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
+ vec3 sun_contrib = min(da, shadow) * sunlit;
+ color.rgb += sun_contrib;
+ color *= diffcol.rgb;
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ if (final_specular.a > 0.0) // specular reflection
+ {
+ float sa = dot(normalize(refnormpersp), light_dir.xyz);
+ vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, final_specular.a)).r);
+
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * final_specular.rgb;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
+
+ color += spec_contrib;
+
+ applyGlossEnv(color, glossenv, final_specular, pos.xyz, norm.xyz);
+ }
+
+ color = mix(color.rgb, diffcol.rgb, diffuse.a);
+
+ if (env_intensity > 0.0)
+ { // add environmentmap
+ applyLegacyEnv(color, legacyenv, final_specular, pos.xyz, norm.xyz, env_intensity);
+ }
+
+ color.rgb = mix(atmosFragLightingLinear(color.rgb, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), diffuse.a);
+ color.rgb = scaleSoftClipFragLinear(color.rgb);
+
+#ifdef WATER_FOG
+ vec4 temp = applyWaterFogView(pos, vec4(color, 0.0));
+ color = temp.rgb;
+#endif
+
+ vec3 npos = normalize(-pos.xyz);
+ 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, light_attenuation[i].w );
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ color += light;
+
+ float al = diffcol.a*vertex_color.a;
+
+ frag_color = vec4(color, al);
+#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
+
+ // deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
+ frag_data[0] = final_color; // gbuffer is sRGB for legacy materials
+ frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
+#endif
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
new file mode 100644
index 0000000000..6dd446d9f7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -0,0 +1,195 @@
+/**
+ * @file class3\deferred\multiPointLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect depthMap;
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+uniform sampler2D noiseMap;
+uniform sampler2D lightFunc;
+
+uniform vec3 env_mat[3];
+uniform float sun_wash;
+uniform int light_count;
+uniform vec4 light[LIGHT_COUNT]; // .w = size; see C++ fullscreen_lights.push_back()
+uniform vec4 light_col[LIGHT_COUNT]; // .a = falloff
+
+uniform vec2 screen_res;
+uniform float far_z;
+uniform mat4 inv_proj;
+
+VARYING vec4 vary_fragcoord;
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec4 getPosition(vec2 pos_screen);
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec2 getScreenXY(vec4 clip);
+vec3 srgb_to_linear(vec3 c);
+
+// Util
+vec3 hue_to_rgb(float hue);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+
+void main()
+{
+#if defined(LOCAL_LIGHT_KILL)
+ discard; // Bail immediately
+#else
+ vec3 final_color = vec3(0, 0, 0);
+ vec2 tc = getScreenXY(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
+ if (pos.z < far_z)
+ {
+ discard;
+ }
+
+ float envIntensity; // not used for this shader
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+
+ vec4 spec = texture2DRect(specularRect, tc);
+ vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
+
+ vec3 h, l, v = -normalize(pos);
+ float nh, nv, vh, lightDist;
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ for (int light_idx = 0; light_idx < LIGHT_COUNT; ++light_idx)
+ {
+ vec3 lightColor = light_col[ light_idx ].rgb; // Already in linear, see pipeline.cpp: volume->getLightLinearColor();
+ float falloff = light_col[ light_idx ].a;
+ float lightSize = light[ light_idx ].w;
+ vec3 lv = light[ light_idx ].xyz - pos;
+
+ lightDist = length(lv);
+
+ float dist = lightDist / lightSize;
+ if (dist <= 1.0)
+ {
+ lv /= lightDist;
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ vec3 intensity = dist_atten * lightColor * 3.0;
+
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
+ }
+ }
+ }
+ else
+ {
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
+
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
+ for (int i = 0; i < LIGHT_COUNT; ++i)
+ {
+ vec3 lv = light[i].xyz - pos;
+ float dist = length(lv);
+ dist /= light[i].w;
+ if (dist <= 1.0)
+ {
+ float nl = dot(n, lv);
+ if (nl > 0.0)
+ {
+ float lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ float fa = light_col[i].a;
+ float dist_atten = calcLegacyDistanceAttenuation(dist, fa);
+ dist_atten *= noise;
+
+ float lit = nl * dist_atten;
+
+ vec3 col = light_col[i].rgb * lit * diffuse;
+
+ if (spec.a > 0.0)
+ {
+ lit = min(nl * 6.0, 1.0) * dist_atten;
+ float fres = pow(1 - vh, 5) * 0.4 + 0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * nl);
+ col += lit * scol * light_col[i].rgb * spec.rgb;
+ }
+ }
+
+ final_color += col;
+ }
+ }
+ }
+ }
+
+ frag_color.rgb = final_color;
+ frag_color.a = 0.0;
+#endif // LOCAL_LIGHT_KILL
+
+#ifdef IS_AMD_CARD
+ // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage
+ // away which leads to unfun crashes and artifacts.
+ vec4 dummy1 = light[0];
+ vec4 dummy2 = light_col[0];
+ vec4 dummy3 = light[LIGHT_COUNT - 1];
+ vec4 dummy4 = light_col[LIGHT_COUNT - 1];
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl
index 9d872b8df8..ad6a0fa752 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/softenLightV.glsl
+ * @file class3\deferred\multiPointLightV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -22,17 +22,18 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-ATTRIBUTE vec3 position;
-
-VARYING vec2 vary_fragcoord;
uniform mat4 modelview_projection_matrix;
-uniform vec2 screen_res;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec4 vary_fragcoord;
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+ vary_fragcoord = pos;
+
+ gl_Position = pos;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
index 9d62b9d180..cb8877ebe5 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -1,9 +1,9 @@
/**
- * @file multiSpotLightF.glsl
+ * @file class3\deferred\multiSpotLightF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -38,10 +38,11 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
+uniform sampler2D projectionMap; // rgba
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
@@ -61,6 +62,7 @@ uniform float sun_wash;
uniform int proj_shadow_idx;
uniform float shadow_fade;
+// Light params
uniform vec3 center;
uniform float size;
uniform vec3 color;
@@ -71,221 +73,198 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec3 getNorm(vec2 pos_screen);
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec3 colorized_dot(float x);
+bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
+vec2 getScreenXY(vec4 clip);
+vec3 srgb_to_linear(vec3 cs);
+vec4 texture2DLodSpecular(vec2 tc, float lod);
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
+vec4 getPosition(vec2 pos_screen);
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
+const float M_PI = 3.14159265;
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+void main()
{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
-
-
-vec4 getPosition(vec2 pos_screen);
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
+ vec3 final_color = vec3(0,0,0);
+ vec2 tc = getScreenXY(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
-void main()
-{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
+ vec3 lv;
+ vec4 proj_tc;
+ float dist, l_dist;
+ if (clipProjectedLightVars(center, pos, dist, l_dist, lv, proj_tc))
{
discard;
}
-
+
float shadow = 1.0;
if (proj_shadow_idx >= 0)
{
- vec4 shd = texture2DRect(lightMap, frag.xy);
- shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
+ vec4 shd = texture2DRect(lightMap, tc);
+ shadow = (proj_shadow_idx==0)?shd.b:shd.a;
shadow += shadow_fade;
shadow = clamp(shadow, 0.0, 1.0);
}
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
-
- float envIntensity = norm.z;
- norm = getNorm(frag.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = (falloff*0.5)+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity);
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
if (dist_atten <= 0.0)
{
discard;
}
-
+
lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
+ vec3 h, l, v = -normalize(pos);
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
- vec3 col = vec3(0,0,0);
+ vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
+ vec4 spec = texture2DRect(specularRect, tc);
+ vec3 dlit = vec3(0, 0, 0);
+ vec3 slit = vec3(0, 0, 0);
+
+ vec3 amb_rgb = vec3(0);
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
- vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
- vec3 dlit = vec3(0, 0, 0);
+ // We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
+ if (proj_tc.x > 0.0 && proj_tc.x < 1.0
+ && proj_tc.y > 0.0 && proj_tc.y < 1.0)
+ {
+ float lit = 0.0;
+ float amb_da = 0.0;
+
+ if (nl > 0.0)
+ {
+ amb_da += (nl*0.5 + 0.5) * proj_ambiance;
+
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
+
+ vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
+ }
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
+ final_color += diffuse.rgb * amb_rgb;
+ }
+ }
+ else
{
- float amb_da = proj_ambiance;
- float lit = 0.0;
- if (da > 0.0)
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
+ if (proj_tc.z > 0.0 &&
+ proj_tc.x < 1.0 &&
+ proj_tc.y < 1.0 &&
+ proj_tc.x > 0.0 &&
+ proj_tc.y > 0.0)
{
- lit = da * dist_atten * noise;
+ float amb_da = 0;
+ float lit = 0.0;
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
+ if (nl > 0.0)
+ {
+ lit = nl * dist_atten * noise;
+
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
+
+ final_color = dlit*lit*diffuse*shadow;
+
+ // unshadowed for consistency between forward and deferred?
+ amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+ }
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
- amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy );
+ final_color += diffuse.rgb * amb_rgb;
}
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance;
-
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
+ if (spec.a > 0.0)
+ {
+ dlit *= min(nl*6.0, 1.0) * dist_atten;
- if (spec.a > 0.0)
- {
- vec3 npos = -normalize(pos);
- dlit *= 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));
+ float fres = pow(1 - vh, 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb*shadow;
- //col += spec.rgb;
- }
- }
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ final_color += speccol;
+ }
+ }
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
+ if (envIntensity > 0.0)
+ {
+ vec3 ref = reflect(normalize(pos), n);
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float ds = dot(ref, proj_n);
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
- if (stc.z > 0.0)
- {
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
+ if (stc.z > 0.0)
{
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ stc /= stc.w;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ final_color += color.rgb * texture2DLodSpecular(stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
}
}
}
}
//not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
-
- col = scaleDownLight(col);
+ final_color = max(final_color, vec3(0.0));
- //output linear space color as gamma correction happens down stream
- frag_color.rgb = col;
+ //output linear
+ frag_color.rgb = final_color;
frag_color.a = 0.0;
+#endif // LOCAL_LIGHT_KILL
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
new file mode 100644
index 0000000000..cdffcf103d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -0,0 +1,156 @@
+/**
+ * @file class3\deferred\pointLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+uniform sampler2D noiseMap;
+uniform sampler2D lightFunc;
+uniform sampler2DRect depthMap;
+
+uniform vec3 env_mat[3];
+uniform float sun_wash;
+
+// light params
+uniform vec3 color;
+uniform float falloff;
+uniform float size;
+
+VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
+
+uniform vec2 screen_res;
+
+uniform mat4 inv_proj;
+uniform vec4 viewport;
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec4 getPosition(vec2 pos_screen);
+vec2 getScreenXY(vec4 clip);
+vec3 srgb_to_linear(vec3 c);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+void main()
+{
+ vec3 final_color = vec3(0);
+ vec2 tc = getScreenXY(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
+
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+
+ vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
+ vec4 spec = texture2DRect(specularRect, tc);
+
+ // Common half vectors calcs
+ vec3 lv = trans_center.xyz-pos;
+ vec3 h, l, v = -normalize(pos);
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ if (lightDist >= size)
+ {
+ discard;
+ }
+ float dist = lightDist / size;
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ vec3 intensity = dist_atten * color * 3.0; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
+ }
+ else
+ {
+ if (nl < 0.0)
+ {
+ discard;
+ }
+
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
+ float lit = nl * dist_atten * noise;
+
+ final_color = color.rgb*lit*diffuse;
+
+ if (spec.a > 0.0)
+ {
+ lit = min(nl*6.0, 1.0) * dist_atten;
+
+ float sa = nh;
+ float fres = pow(1 - vh, 5) * 0.4+0.5;
+ float gtdenom = 2 * nh;
+ float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh)));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ final_color += lit*scol*color.rgb*spec.rgb;
+ }
+ }
+
+ if (dot(final_color, final_color) <= 0.0)
+ {
+ discard;
+ }
+ }
+
+ frag_color.rgb = final_color;
+ frag_color.a = 0.0;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl
index db8c75fb8a..d42c8f6cf6 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/shadowCubeV.glsl
+ * @file class3\deferred\pointLightV.glsl
*
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -24,27 +24,22 @@
*/
uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
ATTRIBUTE vec3 position;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
+uniform vec3 center;
+uniform float size;
-uniform vec3 box_center;
-uniform vec3 box_size;
+VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
void main()
{
//transform vertex
- vec3 p = position*box_size+box_center;
- vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
-
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
+ vec3 p = position*size+center;
+ vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0);
+ vary_fragcoord = pos;
+ trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz;
gl_Position = pos;
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
new file mode 100644
index 0000000000..ca436033f1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -0,0 +1,572 @@
+/**
+ * @file class3/deferred/reflectionProbeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#define FLT_MAX 3.402823466e+38
+
+#define REFMAP_COUNT 256
+#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider
+
+uniform samplerCubeArray reflectionProbes;
+uniform samplerCubeArray irradianceProbes;
+
+layout (std140) uniform ReflectionProbes
+{
+ // list of OBBs for user override probes
+ // box is a set of 3 planes outward facing planes and the depth of the box along that plane
+ // for each box refBox[i]...
+ /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation
+ // box[3][0..2] - plane thickness
+ mat4 refBox[REFMAP_COUNT];
+ // list of bounding spheres for reflection probes sorted by distance to camera (closest first)
+ vec4 refSphere[REFMAP_COUNT];
+ // extra parameters (currently only .x used for probe ambiance)
+ vec4 refParams[REFMAP_COUNT];
+ // index of cube map in reflectionProbes for a corresponding reflection probe
+ // e.g. cube map channel of refSphere[2] is stored in refIndex[2]
+ // refIndex.x - cubemap channel in reflectionProbes
+ // refIndex.y - index in refNeighbor of neighbor list (index is ivec4 index, not int index)
+ // refIndex.z - number of neighbors
+ // refIndex.w - priority, if negative, this probe has a box influence
+ ivec4 refIndex[REFMAP_COUNT];
+
+ // neighbor list data (refSphere indices, not cubemap array layer)
+ ivec4 refNeighbor[1024];
+
+ // number of reflection probes present in refSphere
+ int refmapCount;
+};
+
+// Inputs
+uniform mat3 env_mat;
+
+// list of probeIndexes shader will actually use after "getRefIndex" is called
+// (stores refIndex/refSphere indices, NOT rerflectionProbes layer)
+int probeIndex[REF_SAMPLE_COUNT];
+
+// number of probes stored in probeIndex
+int probeInfluences = 0;
+
+bool isAbove(vec3 pos, vec4 plane)
+{
+ return (dot(plane.xyz, pos) + plane.w) > 0;
+}
+
+int max_priority = 0;
+
+// return true if probe at index i influences position pos
+bool shouldSampleProbe(int i, vec3 pos)
+{
+ if (refIndex[i].w < 0)
+ {
+ vec4 v = refBox[i] * vec4(pos, 1.0);
+ if (abs(v.x) > 1 ||
+ abs(v.y) > 1 ||
+ abs(v.z) > 1)
+ {
+ return false;
+ }
+
+ max_priority = max(max_priority, -refIndex[i].w);
+ }
+ else
+ {
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d = dot(delta, delta);
+ float r2 = refSphere[i].w;
+ r2 *= r2;
+
+ if (d > r2)
+ { //outside bounding sphere
+ return false;
+ }
+
+ max_priority = max(max_priority, refIndex[i].w);
+ }
+
+ return true;
+}
+
+// call before sampleRef
+// populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT
+// overall algorithm --
+void preProbeSample(vec3 pos)
+{
+ // TODO: make some sort of structure that reduces the number of distance checks
+ for (int i = 1; i < refmapCount; ++i)
+ {
+ // found an influencing probe
+ if (shouldSampleProbe(i, pos))
+ {
+ probeIndex[probeInfluences] = i;
+ ++probeInfluences;
+
+ int neighborIdx = refIndex[i].y;
+ if (neighborIdx != -1)
+ {
+ int neighborCount = min(refIndex[i].z, REF_SAMPLE_COUNT-1);
+
+ int count = 0;
+ while (count < neighborCount)
+ {
+ // check up to REF_SAMPLE_COUNT-1 neighbors (neighborIdx is ivec4 index)
+
+ int idx = refNeighbor[neighborIdx].x;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ return;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ return;
+ }
+
+ idx = refNeighbor[neighborIdx].y;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ return;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ return;
+ }
+
+ idx = refNeighbor[neighborIdx].z;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ return;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ return;
+ }
+
+ idx = refNeighbor[neighborIdx].w;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ return;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ return;
+ }
+
+ ++neighborIdx;
+ }
+
+ return;
+ }
+ }
+ }
+
+ if (probeInfluences == 0)
+ { // probe at index 0 is a special fallback probe
+ probeIndex[0] = 0;
+ probeInfluences = 1;
+ }
+}
+
+// from https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
+
+// original reference implementation:
+/*
+bool intersect(const Ray &ray) const
+{
+ float t0, t1; // solutions for t if the ray intersects
+#if 0
+ // geometric solution
+ Vec3f L = center - orig;
+ float tca = L.dotProduct(dir);
+ // if (tca < 0) return false;
+ float d2 = L.dotProduct(L) - tca * tca;
+ if (d2 > radius2) return false;
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+#else
+ // analytic solution
+ Vec3f L = orig - center;
+ float a = dir.dotProduct(dir);
+ float b = 2 * dir.dotProduct(L);
+ float c = L.dotProduct(L) - radius2;
+ if (!solveQuadratic(a, b, c, t0, t1)) return false;
+#endif
+ if (t0 > t1) std::swap(t0, t1);
+
+ if (t0 < 0) {
+ t0 = t1; // if t0 is negative, let's use t1 instead
+ if (t0 < 0) return false; // both t0 and t1 are negative
+ }
+
+ t = t0;
+
+ return true;
+} */
+
+// adapted -- assume that origin is inside sphere, return intersection of ray with edge of sphere
+vec3 sphereIntersect(vec3 origin, vec3 dir, vec3 center, float radius2)
+{
+ float t0, t1; // solutions for t if the ray intersects
+
+ vec3 L = center - origin;
+ float tca = dot(L,dir);
+
+ float d2 = dot(L,L) - tca * tca;
+
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+
+ vec3 v = origin + dir * t1;
+ return v;
+}
+
+// from https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
+/*
+vec3 DirectionWS = normalize(PositionWS - CameraWS);
+vec3 ReflDirectionWS = reflect(DirectionWS, NormalWS);
+
+// Intersection with OBB convertto unit box space
+// Transform in local unit parallax cube space (scaled and rotated)
+vec3 RayLS = MulMatrix( float(3x3)WorldToLocal, ReflDirectionWS);
+vec3 PositionLS = MulMatrix( WorldToLocal, PositionWS);
+
+vec3 Unitary = vec3(1.0f, 1.0f, 1.0f);
+vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
+vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
+vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect);
+float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z));
+
+// Use Distance in WS directly to recover intersection
+vec3 IntersectPositionWS = PositionWS + ReflDirectionWS * Distance;
+vec3 ReflDirectionWS = IntersectPositionWS - CubemapPositionWS;
+
+return texCUBE(envMap, ReflDirectionWS);
+*/
+
+// get point of intersection with given probe's box influence volume
+// origin - ray origin in clip space
+// dir - ray direction in clip space
+// i - probe index in refBox/refSphere
+vec3 boxIntersect(vec3 origin, vec3 dir, int i)
+{
+ // Intersection with OBB convertto unit box space
+ // Transform in local unit parallax cube space (scaled and rotated)
+ mat4 clipToLocal = refBox[i];
+
+ vec3 RayLS = mat3(clipToLocal) * dir;
+ vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz;
+
+ vec3 Unitary = vec3(1.0f, 1.0f, 1.0f);
+ vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
+ vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
+ vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect);
+ float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z));
+
+ // Use Distance in CS directly to recover intersection
+ vec3 IntersectPositionCS = origin + dir * Distance;
+
+ return IntersectPositionCS;
+}
+
+
+
+// Tap a reflection probe
+// pos - position of pixel
+// dir - pixel normal
+// vi - return value of intersection point with influence volume
+// wi - return value of approximate world space position of sampled pixel
+// lod - which mip to bias towards (lower is higher res, sharper reflections)
+// c - center of probe
+// r2 - radius of probe squared
+// i - index of probe
+vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float lod, vec3 c, int i)
+{
+ //lod = max(lod, 1);
+ // parallax adjustment
+
+ vec3 v;
+
+ if (refIndex[i].w < 0)
+ {
+ v = boxIntersect(pos, dir, i);
+ w = 1.0;
+ }
+ else
+ {
+ float r = refSphere[i].w; // radius of sphere volume
+ float rr = r * r; // radius squared
+
+ v = sphereIntersect(pos, dir, c, rr);
+
+ float p = float(abs(refIndex[i].w)); // priority
+
+ float r1 = r * 0.1; // 90% of radius (outer sphere to start interpolating down)
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d2 = max(dot(delta, delta), 0.001);
+ float r2 = r1 * r1;
+
+ float atten = 1.0 - max(d2 - r2, 0.0) / max((rr - r2), 0.001);
+
+ w = 1.0 / d2;
+ w *= atten;
+ }
+
+ vi = v;
+
+ v -= c;
+ vec3 d = normalize(v);
+
+ v = env_mat * v;
+
+ vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod);
+
+ wi = d * ret.a * 256.0+c;
+
+ return ret.rgb;
+}
+
+// Tap an irradiance map
+// pos - position of pixel
+// dir - pixel normal
+// c - center of probe
+// r2 - radius of probe squared
+// i - index of probe
+vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
+{
+ // parallax adjustment
+ vec3 v;
+ if (refIndex[i].w < 0)
+ {
+ v = boxIntersect(pos, dir, i);
+ w = 1.0;
+ }
+ else
+ {
+ float r = refSphere[i].w; // radius of sphere volume
+ float p = float(abs(refIndex[i].w)); // priority
+ float rr = r * r; // radius squred
+
+ v = sphereIntersect(pos, dir, c, rr);
+
+ float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down)
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d2 = dot(delta, delta);
+ float r2 = r1 * r1;
+
+ w = 1.0 / d2;
+
+ float atten = 1.0 - max(d2 - r2, 0.0) / (rr - r2);
+ w *= atten;
+ }
+
+ v -= c;
+ v = env_mat * v;
+ {
+ return texture(irradianceProbes, vec4(v.xyz, refIndex[i].x)).rgb * refParams[i].x;
+ }
+}
+
+vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)
+{
+ float wsum = 0.0;
+ vec3 col = vec3(0,0,0);
+ float vd2 = dot(pos,pos); // view distance squared
+
+ for (int idx = 0; idx < probeInfluences; ++idx)
+ {
+ int i = probeIndex[idx];
+ if (abs(refIndex[i].w) < max_priority)
+ {
+ continue;
+ }
+
+ float w;
+ vec3 vi, wi;
+ vec3 refcol;
+
+
+ {
+ if (errorCorrect && refIndex[i].w >= 0)
+ { // error correction is on and this probe is a sphere
+ //take a sample to get depth value, then error correct
+ refcol = tapRefMap(pos, dir, w, vi, wi, abs(lod + 2), refSphere[i].xyz, i);
+
+ //adjust lookup by distance result
+ float d = length(vi - wi);
+ vi += dir * d;
+
+ vi -= refSphere[i].xyz;
+
+ vi = env_mat * vi;
+
+ refcol = textureLod(reflectionProbes, vec4(vi, refIndex[i].x), lod).rgb;
+
+ // weight by vector correctness
+ vec3 pi = normalize(wi - pos);
+ w *= max(dot(pi, dir), 0.1);
+ //w = pow(w, 32.0);
+ }
+ else
+ {
+ refcol = tapRefMap(pos, dir, w, vi, wi, lod, refSphere[i].xyz, i);
+ }
+
+ col += refcol.rgb*w;
+
+ wsum += w;
+ }
+ }
+
+ if (wsum > 0.0)
+ {
+ col *= 1.0/wsum;
+ }
+
+ return col;
+}
+
+vec3 sampleProbeAmbient(vec3 pos, vec3 dir)
+{
+ // modified copy/paste of sampleProbes follows, will likely diverge from sampleProbes further
+ // as irradiance map mixing is tuned independently of radiance map mixing
+ float wsum = 0.0;
+ vec3 col = vec3(0,0,0);
+ float vd2 = dot(pos,pos); // view distance squared
+
+ float minweight = 1.0;
+
+ for (int idx = 0; idx < probeInfluences; ++idx)
+ {
+ int i = probeIndex[idx];
+ if (abs(refIndex[i].w) < max_priority)
+ {
+ continue;
+ }
+
+ {
+ float w;
+ vec3 refcol = tapIrradianceMap(pos, dir, w, refSphere[i].xyz, i);
+
+ col += refcol*w;
+
+ wsum += w;
+ }
+ }
+
+ if (wsum > 0.0)
+ {
+ col *= 1.0/wsum;
+ }
+
+ return col;
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+{
+ // TODO - don't hard code lods
+ float reflection_lods = 6;
+ preProbeSample(pos);
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ ambenv = sampleProbeAmbient(pos, norm);
+
+ float lod = (1.0-glossiness)*reflection_lods;
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod, errorCorrect);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness)
+{
+ sampleReflectionProbes(ambenv, glossenv,
+ pos, norm, glossiness, false);
+}
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity)
+{
+ // TODO - don't hard code lods
+ float reflection_lods = 7;
+ preProbeSample(pos);
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ ambenv = sampleProbeAmbient(pos, norm);
+
+ if (glossiness > 0.0)
+ {
+ float lod = (1.0-glossiness)*reflection_lods;
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod, false);
+ }
+
+ if (envIntensity > 0.0)
+ {
+ legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, false);
+ }
+}
+
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
+{
+ glossenv *= 0.5; // fudge darker
+ float fresnel = clamp(1.0+dot(normalize(pos.xyz), norm.xyz), 0.3, 1.0);
+ fresnel *= fresnel;
+ fresnel *= spec.a;
+ glossenv *= spec.rgb*fresnel;
+ glossenv *= vec3(1.0) - color; // fake energy conservation
+ color.rgb += glossenv*0.5;
+}
+
+ void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity)
+ {
+ vec3 reflected_color = legacyenv;
+ vec3 lookAt = normalize(pos);
+ float fresnel = 1.0+dot(lookAt, norm.xyz);
+ fresnel *= fresnel;
+ fresnel = min(fresnel+envIntensity, 1.0);
+ reflected_color *= (envIntensity*fresnel);
+ color = mix(color.rgb, reflected_color*0.5, envIntensity);
+ }
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
deleted file mode 100644
index c8991f7a18..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file class3/deferred/shVisF.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_color;
-#else
- #define frag_color gl_FragColor
-#endif
-
-/////////////////////////////////////////////////////////////////////////
-// Fragment shader for L1 SH debug rendering
-/////////////////////////////////////////////////////////////////////////
-
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-uniform mat3 inv_modelviewprojection;
-
-VARYING vec4 vary_pos;
-
-void main(void)
-{
- vec2 coord = vary_pos.xy + vec2(0.5,0.5);
-
- coord.x *= (1.6/0.9);
-
- if (dot(coord, coord) > 0.25)
- {
- discard;
- }
-
- vec4 n = vec4(coord*2.0, 0.0, 1);
- //n.y = -n.y;
- n.z = sqrt(max(1.0-n.x*n.x-n.y*n.y, 0.0));
- //n.xyz = inv_modelviewprojection * n.xyz;
-
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
- vec3 indirect = vec3(
- dot(l1r, l1tap * n),
- dot(l1g, l1tap * n),
- dot(l1b, l1tap * n));
-
- //indirect = pow(indirect, vec3(0.45));
- indirect *= 3.0;
-
- frag_color = vec4(indirect, 1.0);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
deleted file mode 100644
index 345c07a354..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file shadowAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 pos;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
-
- frag_color = computeMoments(length(pos), float a);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
-#endif
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
deleted file mode 100644
index af1461c297..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file shadowAlphaMaskV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float target_pos_x;
-VARYING vec4 pos;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- vec4 pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
- pos_w = pos.w;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
deleted file mode 100644
index 50f1ffd626..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @file class3/deferred/shadowAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec4 getPosition(vec2 screen_coord);
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- vec4 pos = getPosition(vary_texcoord0.xy);
-
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
-
- if (alpha < 0.05) // treat as totally transparent
- {
- discard;
- }
-
- if (alpha < 0.88) // treat as semi-transparent
- {
- if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
- {
- discard;
- }
- }
-
- frag_color = computeMoments(length(pos.xyz), alpha);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
deleted file mode 100644
index 6a646f5e9e..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file class3/deferred/shadowAlphaMaskV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
-
- pos = modelview_projection_matrix * pre_pos;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
deleted file mode 100644
index 3350267130..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file class3/deferred/shadowF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- frag_color = computeMoments(length(pos), 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
deleted file mode 100644
index 2f69a353e8..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * @file class3/deferred/shadowUtil.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 sampler2D shadowMap0;
-uniform sampler2D shadowMap1;
-uniform sampler2D shadowMap2;
-uniform sampler2D shadowMap3;
-uniform sampler2D shadowMap4;
-uniform sampler2D shadowMap5;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-uniform vec2 shadow_res;
-uniform vec2 proj_shadow_res;
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float shadow_bias;
-
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
-
-float getDepth(vec2 screenpos);
-vec3 getNorm(vec2 screenpos);
-vec4 getPosition(vec2 pos_screen);
-
-float ReduceLightBleeding(float p_max, float Amount)
-{
- return smoothstep(Amount, 1, p_max);
-}
-
-float ChebyshevUpperBound(vec2 m, float t, float min_v, float Amount)
-{
- float p = (t <= m.x) ? 1.0 : 0.0;
-
- float v = m.y - (m.x*m.x);
- v = max(v, min_v);
-
- float d = t - m.x;
-
- float p_max = v / (v + d*d);
-
- p_max = ReduceLightBleeding(p_max, Amount);
-
- return max(p, p_max);
-}
-
-vec4 computeMoments(float depth, float a)
-{
- float m1 = depth;
- float dx = dFdx(depth);
- float dy = dFdy(depth);
- float m2 = m1*m1 + 0.25 * a * (dx*dx + dy*dy);
- return vec4(m1, m2, a, max(dx, dy));
-}
-
-float vsmDirectionalSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix)
-{
- vec4 lpos = shadowMatrix * stc;
- vec4 moments = texture2D(shadowMap, lpos.xy);
- return ChebyshevUpperBound(moments.rg, depth - shadow_bias * 256.0f, 0.125, 0.9);
-}
-
-float vsmSpotSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix)
-{
- vec4 lpos = shadowMatrix * stc;
- vec4 moments = texture2D(shadowMap, lpos.xy);
- lpos.xyz /= lpos.w;
- lpos.xy *= 0.5;
- lpos.xy += 0.5;
- return ChebyshevUpperBound(moments.rg, depth - spot_shadow_bias * 16.0f, 0.125, 0.9);
-}
-
-#if VSM_POINT_SHADOWS
-float vsmPointSample(float lightDistance, vec3 lightDirection, samplerCube shadow_cube_map)
-{
- vec4 moments = textureCube(shadow_cube_map, light_direction);
- return ChebyshevUpperBound(moments.rg, light_distance, 0.01, 0.25);
-}
-#endif
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
-{
- if (pos.z < -shadow_clip.w)
- {
- discard;
- }
-
- float depth = getDepth(pos_screen);
-
- vec4 spos = vec4(pos,1.0);
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
-
- float shadow = 0.0f;
- float weight = 1.0;
-
- if (spos.z < near_split.z)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap3, shadow_matrix[3]);
- weight += 1.0f;
- }
- if (spos.z < near_split.y)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap2, shadow_matrix[2]);
- weight += 1.0f;
- }
- if (spos.z < near_split.x)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap1, shadow_matrix[1]);
- weight += 1.0f;
- }
- if (spos.z > far_split.x)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap0, shadow_matrix[0]);
- weight += 1.0f;
- }
-
- shadow /= weight;
-
- return shadow;
-}
-
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
-{
- if (pos.z < -shadow_clip.w)
- {
- discard;
- }
-
- float depth = getDepth(pos_screen);
-
- pos += norm * spot_shadow_offset;
- return vsmSpotSample(vec4(pos, 1.0), depth, (index == 0) ? shadowMap4 : shadowMap5, shadow_matrix[4 + index]);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
deleted file mode 100644
index 6577fe0ecf..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file class3/deferred/shadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-uniform mat4 texture_matrix0;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
-
- pos = modelview_projection_matrix * pre_pos;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
deleted file mode 100644
index a0b082ed7c..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * @file class3/deferred/skyF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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
-
-VARYING vec2 vary_frag;
-
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-uniform mat4 inv_proj;
-uniform mat4 inv_modelview;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-uniform sampler2D rainbow_map;
-uniform sampler2D halo_map;
-
-uniform float moisture_level;
-uniform float droplet_radius;
-uniform float ice_level;
-
-vec3 GetSolarLuminance();
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
-
-vec3 ColorFromRadiance(vec3 radiance);
-vec3 rainbow(float d)
-{
- // d is the dot product of view and sun directions, so ranging -1.0..1.0
- // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
- // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
-
- // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
- // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
- // interesting range, but in reversed order: i.e. d = (1 - d) - 1.575
- d = clamp(-0.575 - d, 0.0, 1.0);
-
- // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
- // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
- // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
- float interior_coord = max(0.0, d - 0.25) * 4.2857;
- d = clamp(d, 0.0, 0.25) + interior_coord;
-
- float rad = (droplet_radius - 5.0f) / 1024.0f;
- return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
-}
-
-vec3 halo22(float d)
-{
- float v = sqrt(max(0, 1 - (d*d)));
- return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
-}
-
-void main()
-{
- vec3 pos = vec3((vary_frag * 2.0) - vec2(1.0, 1.0f), 1.0);
- vec4 view_pos = (inv_proj * vec4(pos, 1.0f));
-
- view_pos /= view_pos.w;
-
- vec3 view_ray = (inv_modelview * vec4(view_pos.xyz, 0.0f)).xyz + camPosLocal;
-
- vec3 view_direction = normalize(view_ray);
- vec3 sun_direction = normalize(sun_dir);
- vec3 earth_center = vec3(0, 0, -6360.0f);
- vec3 camPos = (camPosLocal / 1000.0f) - earth_center;
-
- vec3 transmittance;
- vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance);
- vec3 solar_luminance = GetSolarLuminance();
-
- // If the view ray intersects the Sun, add the Sun radiance.
- float s = dot(view_direction, sun_direction);
-
- // cheesy solar disc...
- if (s >= (sun_size * 0.999))
- {
- radiance_sun += pow(smoothstep(0.0, 1.3, (s - (sun_size * 0.9))), 2.0) * solar_luminance * transmittance;
- }
- s = smoothstep(0.9, 1.0, s) * 16.0f;
-
- vec3 color = ColorFromRadiance(radiance_sun);
-
- float optic_d = dot(view_direction, sun_direction);
- vec3 halo_22 = halo22(optic_d);
-
- color.rgb += rainbow(optic_d) * optic_d;
- color.rgb += halo_22;
-
- color = pow(color, vec3(1.0/2.2));
-
- frag_data[0] = vec4(color, 1.0 + s);
- frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 7ed9e7b4fc..879f4ef510 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -1,31 +1,35 @@
-/**
+/**
* @file class3/deferred/softenLightF.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$
*/
-
+
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
-/*[EXTRA_CODE_HERE]*/
+#define FLT_MAX 3.402823466e+38
+
+#define REFMAP_COUNT 256
+#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -36,142 +40,205 @@ out vec4 frag_color;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+uniform sampler2D altDiffuseMap; // PBR: irradiance, skins/default/textures/default_irradiance.png
+
+const float M_PI = 3.14159265;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
uniform sampler2DRect lightMap;
+#endif
+
uniform sampler2DRect depthMap;
uniform sampler2D lightFunc;
-uniform samplerCube environmentMap;
uniform float blur_size;
uniform float blur_fidelity;
// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-uniform float cloud_shadow;
-uniform float max_y;
-uniform vec4 glow;
uniform mat3 env_mat;
-uniform vec4 shadow_clip;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
-uniform mat4 inv_modelview;
-
uniform vec2 screen_res;
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFragLinear(vec3 l);
+vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten);
-vec3 GetSunAndSkyIrradiance(vec3 camPos, vec3 norm, vec3 dir, out vec3 sky_irradiance);
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
+// reflection probe interface
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness);
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
-vec3 ColorFromRadiance(vec3 radiance);
-vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
#endif
-void main()
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
+
+vec3 pbrBaseLight(vec3 diffuseColor,
+ vec3 specularColor,
+ float metallic,
+ vec3 pos,
+ vec3 norm,
+ float perceptualRoughness,
+ vec3 light_dir,
+ vec3 sunlit,
+ float scol,
+ vec3 radiance,
+ vec3 irradiance,
+ vec3 colorEmissive,
+ float ao,
+ vec3 additive,
+ vec3 atten);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+
+void main()
{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPositionWithDepth(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
+ vec2 tc = vary_fragcoord.xy;
+ float depth = texture2DRect(depthMap, tc.xy).r;
+ vec4 pos = getPositionWithDepth(tc, depth);
+ vec4 norm = texture2DRect(normalMap, tc);
float envIntensity = norm.z;
- norm.xyz = getNorm(tc);
+ norm.xyz = getNorm(tc);
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
+ vec4 baseColor = texture2DRect(diffuseRect, tc);
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive
- vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB
- diffuse.rgb = srgb_to_linear(diffuse.rgb);
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+#endif
+
+#if defined(HAS_SUN_SHADOW)
+ float scol = max(scol_ambocc.r, baseColor.a);
+#else
+ float scol = 1.0;
+#endif
+#if defined(HAS_SSAO)
+ float ambocc = scol_ambocc.g;
+#else
+ float ambocc = 1.0;
+#endif
- vec3 col;
+ vec3 color = vec3(0);
float bloom = 0.0;
- {
- vec3 camPos = (camPosLocal / 1000.0f) + vec3(0, 0, 6360.0f);
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
- vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
- float scol = max(scol_ambocc.r, diffuse.a);
+ calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
- float ambocc = scol_ambocc.g;
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 orm = texture2DRect(specularRect, tc).rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ float ao = orm.r * ambocc;
+
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, pos.xyz, norm.xyz, gloss);
+
+ // Take maximium of legacy ambient vs irradiance sample as irradiance
+ // NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
+ irradiance = max(amblit,irradiance);
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
+ vec3 diffuseColor;
+ vec3 specularColor;
+ calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);
- vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
- dot(l1g, l1tap * vec4(1, norm.xyz)),
- dot(l1b, l1tap * vec4(1, norm.xyz)));
+ vec3 v = -normalize(pos.xyz);
+ color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
+ }
+ else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+ {
+ //should only be true of WL sky, just port over base color value
+ color = srgb_to_linear(baseColor.rgb);
+ }
+ else
+ {
+ // legacy shaders are still writng sRGB to gbuffer
+ baseColor.rgb = srgb_to_linear(baseColor.rgb);
+ spec.rgb = srgb_to_linear(spec.rgb);
- indirect = clamp(indirect, vec3(0), vec3(1.0));
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
- vec3 transmittance;
- vec3 sky_irradiance;
- vec3 sun_irradiance = GetSunAndSkyIrradiance(camPos, norm.xyz, sun_dir, sky_irradiance);
- vec3 inscatter = GetSkyLuminanceToPoint(camPos, (pos / 1000.f) + vec3(0, 0, 6360.0f), scol, sun_dir, transmittance);
+ vec3 irradiance = vec3(0);
+ vec3 glossenv = vec3(0);
+ vec3 legacyenv = vec3(0);
- vec3 radiance = scol * (sun_irradiance + sky_irradiance) + inscatter;
- vec3 atmo_color = ColorFromRadiance(radiance);
+ sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
+
+ // use sky settings ambient or irradiance map sample, whichever is brighter
+ irradiance = max(amblit, irradiance);
- col = atmo_color + indirect;
- col *= transmittance;
- col *= diffuse.rgb;
+ // apply lambertian IBL only (see pbrIbl)
+ color.rgb = irradiance * ambocc;
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 sun_contrib = min(da, scol) * sunlit;
+ color.rgb += sun_contrib;
+ color.rgb *= baseColor.rgb;
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- if (spec.a > 0.0) // specular reflection
+ if (spec.a > 0.0) // specular reflection
{
- // the old infinite-sky shiny reflection
- //
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = scol * texture2D(lightFunc, vec2(sa, spec.a)).r * atmo_color;
-
+ float sa = dot(normalize(refnormpersp), light_dir.xyz);
+ vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r);
+
// add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb * 0.25;
- bloom = dot(spec_contrib, spec_contrib);
- col += spec_contrib;
- }
+ vec3 spec_contrib = dumbshiny * spec.rgb;
+ color.rgb += spec_contrib;
- col = mix(col, diffuse.rgb, diffuse.a);
+ // add radiance map
+ applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
+ }
+ color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a);
+
if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
- vec3 sun_direction = (inv_modelview * vec4(sun_dir, 1.0)).xyz;
- vec3 radiance_sun = GetSkyLuminance(camPos, env_vec, 0.0f, sun_direction, transmittance);
- vec3 refcol = ColorFromRadiance(radiance_sun);
- col = mix(col.rgb, refcol, envIntensity);
+ { // add environment map
+ applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
}
-
- /*if (norm.w < 0.5)
- {
- col = scaleSoftClipFrag(col);
- }*/
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
+
+ color = mix(atmosFragLightingLinear(color, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), baseColor.a);
+ color = scaleSoftClipFragLinear(color);
}
- //output linear since gamma correction happens down stream
- frag_color.rgb = col;
- frag_color.a = bloom;
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom));
+ color = fogged.rgb;
+ #endif
+
+ frag_color.rgb = color.rgb; //output linear since local lights will be added to this shader's results
+ frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
index 56b0f4e5ce..3274153a46 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -1,9 +1,9 @@
/**
- * @file spotLightF.glsl
+ * @file class3\deferred\spotLightF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -28,6 +28,16 @@
/*[EXTRA_CODE_HERE]*/
+#define DEBUG_ANY_LIGHT_TYPE 0 // Output green light cone
+#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in green
+#define DEBUG_PBR_LIGHT_TYPE 0 // Show PBR objects in green
+#define DEBUG_PBR_SPOT 0
+#define DEBUG_PBR_SPOT_DIFFUSE 0
+#define DEBUG_PBR_SPOT_SPECULAR 0
+
+#define DEBUG_SPOT_NL 0 // monochome area effected by light
+#define DEBUG_SPOT_ZERO 0 // Output zero for spotlight
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -38,10 +48,11 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
+uniform sampler2D projectionMap; // rgba
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
@@ -71,217 +82,209 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec3 getNorm(vec2 pos_screen);
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
+vec2 getScreenXY(vec4 clip_point);
+vec3 srgb_to_linear(vec3 c);
+vec4 texture2DLodSpecular(vec2 tc, float lod);
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
+vec4 getPosition(vec2 pos_screen);
+const float M_PI = 3.14159265;
-vec4 getPosition(vec2 pos_screen);
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
-void main()
+void main()
{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = trans_center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
+ vec3 final_color = vec3(0,0,0);
+ vec2 tc = getScreenXY(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
+
+ vec3 lv;
+ vec4 proj_tc;
+ float dist, l_dist;
+ if (clipProjectedLightVars(trans_center, pos, dist, l_dist, lv, proj_tc))
{
discard;
}
-
+
float shadow = 1.0;
-
+
if (proj_shadow_idx >= 0)
{
- vec4 shd = texture2DRect(lightMap, frag.xy);
+ vec4 shd = texture2DRect(lightMap, tc);
shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
shadow += shadow_fade;
shadow = clamp(shadow, 0.0, 1.0);
}
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- float envIntensity = norm.z;
- norm = getNorm(frag.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = (falloff*0.5) + 1.0;
- float dist_atten = min(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
if (dist_atten <= 0.0)
{
discard;
}
-
- lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
-
- vec3 col = vec3(0,0,0);
-
- vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
- vec3 dlit = vec3(0, 0, 0);
+ lv = proj_origin-pos.xyz; // NOTE: Re-using lv
+ vec3 h, l, v = -normalize(pos);
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
+ vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
+ vec4 spec = texture2DRect(specularRect, tc);
+ vec3 dlit = vec3(0, 0, 0);
+ vec3 slit = vec3(0, 0, 0);
+
+ vec3 amb_rgb = vec3(0);
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- float amb_da = proj_ambiance;
- float lit = 0.0;
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
- if (da > 0.0)
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ // We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
+ if (proj_tc.x > 0.0 && proj_tc.x < 1.0
+ && proj_tc.y > 0.0 && proj_tc.y < 1.0)
{
- lit = da * dist_atten * noise;
+ float lit = 0.0;
+ float amb_da = 0.0;
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
- amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
- }
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance;
+ if (nl > 0.0)
+ {
+ amb_da += (nl*0.5 + 0.5) * proj_ambiance;
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
-
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
- if (spec.a > 0.0)
+ vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
+ }
+
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
+ final_color += diffuse.rgb * amb_rgb;
+ }
+ }
+ else
{
- dlit *= min(da*6.0, 1.0) * dist_atten;
- vec3 npos = -normalize(pos);
-
- //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)
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
+ if (proj_tc.z > 0.0 &&
+ proj_tc.x < 1.0 &&
+ proj_tc.y < 1.0 &&
+ proj_tc.x > 0.0 &&
+ proj_tc.y > 0.0)
{
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb*shadow;
+ float amb_da = proj_ambiance;
+ float lit = 0.0;
+
+ if (nl > 0.0)
+ {
+ lit = nl * dist_atten * noise;
+
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
+
+ final_color = dlit*lit*diffuse*shadow;
+
+ amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+ }
+
+ vec3 amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy );
+ final_color += diffuse.rgb*amb_rgb;
+ #if DEBUG_LEG_LIGHT_TYPE
+ final_color = vec3(0,0.5,0);
+ #endif
}
- }
-
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
-
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
-
- if (ds < 0.0)
+ if (spec.a > 0.0)
+ {
+ dlit *= min(nl*6.0, 1.0) * dist_atten;
+ float fres = pow(1 - dot(h, v), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ final_color += speccol;
+ }
+ }
+
+ if (envIntensity > 0.0)
{
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ vec3 ref = reflect(normalize(pos), n);
- if (stc.z > 0.0)
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float ds = dot(ref, proj_n);
+
+ if (ds < 0.0)
{
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+
+ if (stc.z > 0.0)
{
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ stc /= stc.w;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ final_color += color.rgb * texture2DLodSpecular(stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
}
}
}
}
-
+
+#if DEBUG_PBR_SPOT_DIFFUSE
+ final_color = vec3(nl * dist_atten);
+#endif
+#if DEBUG_SPOT_NL
+ final_color = vec3(nl);
+#endif
+#if DEBUG_SPOT_ZERO
+ final_color = vec3(0,0,0);
+#endif
+#if DEBUG_ANY_LIGHT_TYPE
+ final_color = vec3(0,0.3333,0);
+#endif
+
//not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
+ final_color = max(final_color, vec3(0.0));
- frag_color.rgb = col;
+ //output linear colors as gamma correction happens down stream
+ frag_color.rgb = final_color;
frag_color.a = 0.0;
+#endif // LOCAL_LIGHT_KILL
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
deleted file mode 100644
index 112b498c90..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file class3\deferred\sunLightF.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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-//class 2, shadows, no SSAO
-
-// Inputs
-VARYING vec2 vary_fragcoord;
-
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
-
-void main()
-{
- vec2 pos_screen = vary_fragcoord.xy;
- vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
-
- frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- frag_color.g = 1.0f;
- frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
deleted file mode 100644
index 342a2ff3ed..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file class3\deferred\sunLightSSAOF.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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-//class 2 -- shadows and SSAO
-
-// Inputs
-VARYING vec2 vary_fragcoord;
-
-uniform vec3 sun_dir;
-
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
-
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
-
-void main()
-{
- vec2 pos_screen = vary_fragcoord.xy;
- vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
-
- frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- frag_color.b = calcAmbientOcclusion(pos, norm, pos_screen);
- frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
deleted file mode 100644
index 41673d1669..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file treeShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-vec4 computeMoments(float d, float a);
-
-void main()
-{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
-
- if (alpha < minimum_alpha)
- {
- discard;
- }
-
- frag_color = computeMoments(length(pos), 1.0);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos.z/pos.w*0.5+0.5, 0.0);
-#endif
-
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
deleted file mode 100644
index 15e769ac10..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file treeShadowV.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 mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-void main()
-{
- //transform vertex
- pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
deleted file mode 100644
index 02000d90ca..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file waterV.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 mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-
-uniform vec2 d1;
-uniform vec2 d2;
-uniform float time;
-uniform vec3 eyeVec;
-uniform float waterHeight;
-
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-VARYING vec4 vary_position;
-
-float wave(vec2 v, float t, float f, vec2 d, float s)
-{
- return (dot(d, v)*f + t*s)*f;
-}
-
-void main()
-{
- //transform vertex
- vec4 pos = vec4(position.xyz, 1.0);
- mat4 modelViewProj = modelview_projection_matrix;
-
- vec4 oPosition;
-
- //get view vector
- vec3 oEyeVec;
- oEyeVec.xyz = pos.xyz-eyeVec;
-
- float d = length(oEyeVec.xy);
- float ld = min(d, 2560.0);
-
- pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
- view.xyz = oEyeVec;
-
- d = clamp(ld/1536.0-0.5, 0.0, 1.0);
- d *= d;
-
- oPosition = vec4(position, 1.0);
- oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
- vary_position = modelview_matrix * oPosition;
- oPosition = modelViewProj * oPosition;
-
- refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
-
- //get wave position parameter (create sweeping horizontal waves)
- vec3 v = pos.xyz;
- v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
-
- //push position for further horizon effect.
- pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
- pos.w = 1.0;
- pos = modelview_matrix*pos;
-
- //pass wave parameters to pixel shader
- vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
- //get two normal map (detail map) texture coordinates
- littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13;
- littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1;
- view.w = bigWave.y;
- refCoord.w = bigWave.x;
-
- gl_Position = oPosition;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index 540226e672..a5e0adf8fa 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file underWaterF.glsl
+ * @file class3\environment\underWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,19 +23,15 @@
* $/LicenseInfo$
*/
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_color;
uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;
+uniform sampler2D bumpMap;
+
+#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
-uniform sampler2D refTex;
uniform sampler2D screenDepth;
+#endif
uniform vec4 fogCol;
uniform vec3 lightDir;
@@ -49,7 +45,7 @@ uniform float kd;
uniform vec4 waterPlane;
uniform vec3 eyeVec;
uniform vec4 waterFogColor;
-uniform float waterFogDensity;
+uniform vec3 waterFogColorLinear;
uniform float waterFogKS;
uniform vec2 screenRes;
@@ -57,47 +53,15 @@ uniform vec2 screenRes;
VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
+in vec3 vary_position;
-vec2 encode_normal(vec3 n);
-
-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 color * D + kc * L;
-}
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
void main()
{
vec4 color;
-
- //get detail normals
+
+ //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;
@@ -106,10 +70,12 @@ void main()
//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(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
+#ifdef TRANSPARENT_WATER
+ vec4 fb = texture2D(screenTex, distort);
+#else
+ vec4 fb = vec4(waterFogColorLinear, 0.0);
+#endif
+
+ frag_color = applyWaterFogViewLinear(vary_position, fb);
}
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
new file mode 100644
index 0000000000..a6517be433
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -0,0 +1,265 @@
+/**
+ * @file waterF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+// class3/environment/waterF.glsl
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+vec3 scaleSoftClipFragLinear(vec3 l);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+
+// PBR interface
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRoughness);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
+#ifdef TRANSPARENT_WATER
+uniform sampler2D screenTex;
+uniform sampler2D screenDepth;
+#endif
+
+uniform sampler2D refTex;
+
+uniform float sunAngle;
+uniform float sunAngle2;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform float refScale;
+uniform float kd;
+uniform vec2 screenRes;
+uniform vec3 normScale;
+uniform float fresnelScale;
+uniform float fresnelOffset;
+uniform float blurMultiplier;
+uniform vec4 waterFogColor;
+uniform vec3 waterFogColorLinear;
+
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+in vec3 vary_position;
+in vec3 vary_normal;
+in vec3 vary_tangent;
+in vec3 vary_light_dir;
+
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+ vec3 n = mix(bump1, bump2, blend_factor);
+ return n;
+}
+
+vec3 srgb_to_linear(vec3 col);
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+
+vec3 vN, vT, vB;
+
+vec3 transform_normal(vec3 vNt)
+{
+ return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness, bool errorCorrect);
+
+vec3 getPositionWithNDC(vec3 ndc);
+
+void main()
+{
+ vec4 color;
+
+ vN = vary_normal;
+ vT = vary_tangent;
+ vB = cross(vN, vT);
+
+ vec3 pos = vary_position.xyz;
+
+ float dist = length(pos.xyz);
+
+ //normalize view vector
+ vec3 viewVec = normalize(pos.xyz);
+
+ //get wave normals
+ vec2 bigwave = vec2(refCoord.w, view.w);
+ vec3 wave1_a = texture(bumpMap, bigwave, -2 ).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1_b = texture(bumpMap2, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+ vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+ vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+ wave1 = transform_normal(wave1);
+ wave2 = transform_normal(wave2);
+ wave3 = transform_normal(wave3);
+
+ vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+
+ //wavef.z *= max(-viewVec.z, 0.1);
+
+ wavef = normalize(wavef);
+
+ //get base fresnel components
+
+ vec3 df = vec3(
+ dot(viewVec, wave1),
+ dot(viewVec, (wave2 + wave3) * 0.5),
+ dot(viewVec, wave3)
+ ) * fresnelScale + fresnelOffset;
+
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+
+ float dist2 = dist;
+ dist = max(dist, 5.0);
+
+ float dmod = sqrt(dist);
+
+ vec2 dmod_scale = vec2(dmod*dmod, dmod);
+
+ float df1 = df.x + df.y + df.z;
+
+ //wavef = normalize(wavef - vary_normal);
+ //wavef = vary_normal;
+
+ vec3 waver = reflect(viewVec, -wavef)*3;
+
+ //figure out distortion vector (ripply)
+ vec2 distort2 = distort + waver.xy * refScale / max(dmod * df1, 1.0);
+ distort2 = clamp(distort2, vec2(0), vec2(0.99));
+
+#ifdef TRANSPARENT_WATER
+ vec4 fb = texture2D(screenTex, distort2);
+ float depth = texture2D(screenDepth, distort2).r;
+ vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
+
+ if (refPos.z > pos.z-0.05)
+ {
+ //we sampled an above water sample, don't distort
+ distort2 = distort;
+ fb = texture2D(screenTex, distort2);
+ depth = texture2D(screenDepth, distort2).r;
+ refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
+ }
+
+ fb = applyWaterFogViewLinear(refPos, fb);
+#else
+ vec4 fb = vec4(waterFogColorLinear.rgb, 0.0);
+#endif
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+ sunlit = vec3(1); // TODO -- figure out why sunlit is breaking at some view angles
+ vec3 v = -viewVec;
+ float NdotV = clamp(abs(dot(wavef.xyz, v)), 0.001, 1.0);
+
+ float metallic = fresnelOffset * 0.1; // fudge -- use fresnelOffset as metalness
+ float roughness = 0.1;
+ float gloss = 1.0 - roughness;
+
+ vec3 baseColor = vec3(0.25);
+ vec3 f0 = vec3(0.04);
+ vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
+ diffuseColor *= gloss;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ vec3 refnorm = normalize(wavef + vary_normal);
+ //vec3 refnorm = wavef;
+
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, pos, refnorm, gloss, true);
+ radiance *= 0.5;
+ irradiance = fb.rgb;
+
+ color.rgb = pbrIbl(diffuseColor, specularColor, radiance, irradiance, gloss, NdotV, 0.0);
+
+ // fudge -- for punctual lighting, pretend water is metallic
+ diffuseColor = vec3(0);
+ specularColor = vec3(1);
+ roughness = 0.1;
+ float scol = 1.0; // TODO -- incorporate shadow map
+
+ //color.rgb += pbrPunctual(diffuseColor, specularColor, roughness, metallic, wavef, v, vary_light_dir) * sunlit * 2.75 * scol;
+
+ //get specular component
+ float spec = clamp(dot(vary_light_dir, (reflect(viewVec, wavef))), 0.0, 1.0);
+
+ //harden specular
+ spec = pow(spec, 128.0);
+
+ color.rgb += spec * specular;
+
+ color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+ color.rgb = scaleSoftClipFragLinear(color.rgb);
+
+ color.a = 0.f;
+ //color.rgb = fb.rgb;
+ //color.rgb = vec3(depth*depth*depth*depth);
+ //color.rgb = srgb_to_linear(normalize(refPos) * 0.5 + 0.5);
+ //color.rgb = srgb_to_linear(normalize(pos) * 0.5 + 0.5);
+ //color.rgb = srgb_to_linear(wavef * 0.5 + 0.5);
+
+ //color.rgb = radiance;
+ frag_color = color;
+
+#if defined(WATER_EDGE)
+ gl_FragDepth = 0.9999847f;
+#endif
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
deleted file mode 100644
index c6ea3ec9d4..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file class3\wl\advancedAtmoF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-in vec3 view_dir;
-
-uniform vec3 cameraPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-
-vec3 GetSolarLuminance();
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 sun_dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 sun_dir, out vec3 transmittance);
-vec3 GetSunAndSkyIlluminance(vec3 pos, vec3 norm, vec3 sun_dir, out vec3 sky_irradiance);
-
-void main()
-{
- vec3 view_direction = normalize(view_dir);
-
- vec3 camPos = cameraPosLocal;
- vec3 transmittance;
- vec3 sky_illum;
- vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_dir, transmittance);
- vec3 radiance2 = GetSunAndSkyIlluminance(camPos, view_direction, sun_dir, sky_illum);
-
- //radiance *= transmittance;
-
- // If the view ray intersects the Sun, add the Sun radiance.
- if (dot(view_direction, sun_dir) >= sun_size)
- {
- radiance = radiance + transmittance * GetSolarLuminance();
- }
-
- //vec3 color = vec3(1.0) - exp(-radiance);
- //color = pow(color, vec3(1.0 / 2.2));
-
- frag_color.rgb = radiance;
-
- frag_color.a = 1.0;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
deleted file mode 100644
index 65bb00b1f6..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file class3\wl\advancedAtmoV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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 mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-// Inputs
-uniform vec3 camPosLocal;
-
-out vec3 view_dir;
-
-void main()
-{
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // this will be normalized in the frag shader...
- view_dir = position.xyz - camPosLocal.xyz;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
deleted file mode 100644
index 2b70ba76dc..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file class3\wl\atmosphericsF.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 getAdditiveColor();
-vec3 getAtmosAttenuation();
-vec3 scaleSoftClipFrag(vec3 light);
-
-uniform int no_atmo;
-
-vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
-{
- if (no_atmo == 1)
- {
- return light;
- }
- light *= atten.r;
- light += additive;
- return light * 2.0;
-}
-
-vec3 atmosLighting(vec3 light)
-{
- return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
-}
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
deleted file mode 100644
index b76192d73f..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file class3\wl\atmosphericsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-// VARYING param funcs
-void setSunlitColor(vec3 v);
-void setAmblitColor(vec3 v);
-void setAdditiveColor(vec3 v);
-void setAtmosAttenuation(vec3 v);
-void setPositionEye(vec3 v);
-
-vec3 getAdditiveColor();
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-void calcAtmospherics(vec3 inPositionEye) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
- vec3 tmpsunlit = vec3(1);
- vec3 tmpamblit = vec3(1);
- vec3 tmpaddlit = vec3(1);
- vec3 tmpattenlit = vec3(1);
- calcAtmosphericVars(inPositionEye, vec3(0), 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit, true);
- setSunlitColor(tmpsunlit);
- setAmblitColor(tmpamblit);
- setAdditiveColor(tmpaddlit);
- setAtmosAttenuation(tmpattenlit);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
deleted file mode 100644
index 545a32a227..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file class3\wl\transportF.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$
- */
-
-//////////////////////////////////////////////////////////
-// The fragment shader for the terrain atmospherics
-//////////////////////////////////////////////////////////
-
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-
-uniform int no_atmo;
-
-vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- if (no_atmo == 1)
- {
- return light;
- }
- // fullbright responds minimally to atmos scatter effects
- light *= min(15.0 * atten.r, 1.0);
- light += (0.1 * additive);
- return light * 2.0;
-}
-
-vec3 atmosTransport(vec3 light)
-{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- float brightness = dot(light.rgb, vec3(0.33333));
- return vec3(1,0,1);
- //return atmosTransportFrag(light * 0.5, additive * (brightness * 0.5 + 0.5), atten);
-}
-
-vec3 fullbrightAtmosTransport(vec3 light)
-{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
-vec3 fullbrightShinyAtmosTransport(vec3 light)
-{
- float brightness = dot(light.rgb, vec3(0.33333));
- return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * brightness), getAtmosAttenuation());
-}
diff --git a/indra/newview/app_settings/shaders/shader_hierarchy.txt b/indra/newview/app_settings/shaders/shader_hierarchy.txt
index 8ef04d8e1f..81e1327178 100644
--- a/indra/newview/app_settings/shaders/shader_hierarchy.txt
+++ b/indra/newview/app_settings/shaders/shader_hierarchy.txt
@@ -1,177 +1,15 @@
-Class 3 is highest quality / lowest performance
-Class 2 is medium quality / medium performance
-Class 1 is lowest quality / highest performance
+Second Life shader variants are referred to as "classes."
-Shaders WILL fall back to "lower" classes for functionality.
+When a shader of a particular class is loaded, a lower class may
+be loaded if the class requested doesn't exist or fails to load
+for any reason. In general, shaders that require more resources
+or later hardware capabilities should be higher class and
+lower classes can be used for fallback implementations or lower
+detail settings.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/avatarV.glsl - gAvatarProgram, gAvatarWaterProgram
- main() - avatar/avatarV.glsl
- getSkinnedTransform() - avatarSkinV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/avatarF.glsl - gAvatarProgram
- main() - avatar/avatarF.glsl
- default_lighting() - lighting/lightF.glsl
- calc_default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/eyeballV.glsl - gAvatarEyeballProgram
- main() - avatar/eyeballV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLightingSpecular() - lighting/lightSpecularV.glsl
- sumLightsSpecular() - lighting/sumLightsSpecularV.glsl
- calcDirectionalLightSpecular() - lighting/lightFuncSpecularV.glsl
- calcPointLightSpecular() - lighting/lightFuncSpecularV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
- atmosGetDiffuseSunlightColor() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/eyeballF.glsl - gAvatarEyeballProgram
- main() - avatar/eyeballF.glsl
- default_lighting() - lighting/lightF.glsl
- calc_default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/pickAvatarV.glsl - gAvatarPickProgram
- main() - avatar/pickAvatarV.glsl
- getSkinnedTransform() - avatarSkinV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/pickAvatarF.glsl - gAvatarPickProgram
- main() - avatar/pickAvatarF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainV.glsl - gTerrainProgram, gTerrainWaterProgram
- texgen_object() - environment/terrainV.glsl
- main() - environment/terrainV.glsl
- texgen_object() - environment/terrainV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainF.glsl - gTerrainProgram
- main() - environment/terrainF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainWaterF.glsl - gTerrainWaterProgram
- main() - environment/terrainWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/underWaterF.glsl - gUnderWaterProgram
- applyWaterFog() - environment/underWaterF.glsl (NOTE: different than one in waterFogF.glsl)
- main() - environment/underWaterF.glsl
- applyWaterFog() - environment/underWaterF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/waterV.glsl - gWaterProgram, gUnderWaterProgram
- main() - environment/waterV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/waterF.glsl - gWaterProgram
- main() - environment/waterF.glsl
- atmosTransport() - windlight/transportF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightV.glsl - gObjectFullbrightProgram, gObjectFullbrightWaterProgram
- main() - objects/fullbrightV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightF.glsl - gObjectFullbrightProgram
- main() - objects/fullbrightF.glsl
- fullbright_lighting() - lighting/lightFullbrightF.glsl
- fullbrightAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- fullbrightScaleSoftClip() - windlight/gammaF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightShinyV.glsl - gObjectFullbrightShinyProgram
- main() - objects/fullbrightShinyV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightShinyF.glsl - gObjectFullbrightShinyProgram
- main() - objects/fullbrightShinyF.glsl
- fullbright_shiny_lighting() - lighting/lightFullbrightShinyF.glsl
- fullbrightShinyAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- fullbrightScaleSoftClip() - windlight/gammaF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightWaterF.glsl - gObjectFullbrightWaterProgram
- main() - objects/fullbrightWaterF.glsl
- fullbright_lighting_water() - lighting/lightFullbrightWaterF.glsl
- fullbrightAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyV.glsl - gObjectShinyProgram, gObjectShinyWaterProgram
- main() - objects/shinyV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- calcLighting(vec4) - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyF.glsl - gObjectShinyProgram
- main() - objects/shinyF.glsl
- shiny_lighting() - lighting/lightShinyF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyWaterF.glsl - gObjectShinyWaterProgram
- main() - objects/shinyWaterF.glsl
- shiny_lighting_water() - lighting/lightShinyWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleV.glsl - gObjectSimpleProgram, gObjectSimpleWaterProgram
- main() - objects/simpleV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleF.glsl - gObjectSimpleProgram
- main() - objects/simpleF.glsl
- default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleWaterF.glsl - gObjectSimpleWaterProgram, gAvatarWaterProgram
- main() - objects/simpleWaterF.glsl
- default_lighting_water() - lighting/lightWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/skyV.glsl - gWLSkyProgram
- main() - windlight/skyV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/skyF.glsl - gWLSkyProgram
- main() - windlight/skyF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/cloudsV.glsl - gWLCloudProgram
- main() - windlight/cloudsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/cloudsF.glsl - gWLCloudProgram
- main() - windlight/cloudsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
+Which class is chosen will generally depend on graphics preferences.
+
+Previously, someone tried to enumerate the shaders here, but don't do
+that. It messes with searches and the shader hierarchy changes often.
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
deleted file mode 100644
index 8462df207b..0000000000
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="TRUE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="1.0"/>
- <!--Short Range-->
- <RenderFarClip value="256"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="9"/>
- <!--Low number-->
- <RenderMaxPartCount value="4096"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="4"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="2.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="1.0"/>
- <!--Avater Impostors and Visual Muting Limits (real defaults set
- based on default graphics setting -->
- <RenderAvatarMaxNonImpostors value="0"/>
- <RenderAvatarMaxComplexity value="350000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1500.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="2.0"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="TRUE"/>
- <!--Deferred Shading-->
- <RenderDeferred value="TRUE"/>
- <!--SSAO Enabled-->
- <RenderDeferredSSAO value="TRUE"/>
- <!--Full Shadows-->
- <RenderShadowDetail value="2"/>
-</settings>
diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml
index 2241a12545..6cfc0b0be2 100644
--- a/indra/newview/character/avatar_skeleton.xml
+++ b/indra/newview/character/avatar_skeleton.xml
@@ -2,15 +2,15 @@
<bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/>
- <bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine1" connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine2" connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
<collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
- <bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine3" connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine4" connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/>
<collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/>
@@ -23,58 +23,58 @@
<bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
- <bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceRoot" connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEyeAltRight" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeAltLeft" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadLeft" connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadRight" connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowOuterLeft" connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowCenterLeft" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowInnerLeft" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowOuterRight" connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowCenterRight" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowInnerRight" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidUpperLeft" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidLowerLeft" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidUpperRight" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidLowerRight" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEar1Left" connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEar2Left" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEar1Right" connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEar2Right" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseLeft" connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseCenter" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseRight" connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekLowerLeft" connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekUpperLeft" connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekLowerRight" connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekUpperRight" connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceJaw" connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceChin" connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTeethLower" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceLipLowerLeft" connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipLowerRight" connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipLowerCenter" connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTongueBase" connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceTongueTip" connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceJawShaper" connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadCenter" connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseBase" connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTeethUpper" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceLipUpperLeft" connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipUpperRight" connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipCornerLeft" connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipCornerRight" connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipUpperCenter" connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyecornerInnerLeft" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyecornerInnerRight" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseBridge" connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -86,29 +86,29 @@
<collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/>
- <bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandMiddle1Left" connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle2Left" connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle3Left" connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandIndex1Left" connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex2Left" connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex3Left" connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandRing1Left" connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing2Left" connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing3Left" connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandPinky1Left" connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky2Left" connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky3Left" connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandThumb1Left" connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb2Left" connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb3Left" connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -123,49 +123,49 @@
<collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/>
- <bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandMiddle1Right" connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle2Right" connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle3Right" connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandIndex1Right" connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex2Right" connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex3Right" connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandRing1Right" connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing2Right" connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing3Right" connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandPinky1Right" connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky2Right" connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky3Right" connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandThumb1Right" connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb2Right" connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb3Right" connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWingsRoot" connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing1Left" connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing2Left" connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing3Left" connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing4Left" connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing4FanLeft" connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing1Right" connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing2Right" connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing3Right" connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing4Right" connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing4FanRight" connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -200,30 +200,30 @@
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mTail1" connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail2" connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail3" connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail4" connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail5" connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail6" connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
- <bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mGroin" connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHindLimbsRoot" connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb1Left" connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb2Left" connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb3Left" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb4Left" connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHindLimb1Right" connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb2Right" connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb3Right" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb4Right" connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae
new file mode 100644
index 0000000000..085b2c7309
--- /dev/null
+++ b/indra/newview/cube.dae
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+ <asset>
+ <contributor>
+ modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26
+ </contributor>
+ <created>2018-10-25T16:29:03Z</created>
+ <modified>2022-02-18T00:00:00Z</modified>
+ <unit meter="1.000000"/>
+ <up_axis>Y_UP</up_axis>
+ </asset>
+
+ <library_materials>
+ <material id="Blue" name="Blue">
+ <instance_effect url="#effect_Blue"/>
+ </material>
+ </library_materials>
+
+
+ <library_effects>
+ <effect id="effect_Blue">
+ <profile_COMMON>
+ <technique sid="common">
+ <phong>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <color>0.137255 0.403922 0.870588 1</color>
+ </diffuse>
+ <specular>
+ <color>0.5 0.5 0.5 1</color>
+ </specular>
+ <shininess>
+ <float>16</float>
+ </shininess>
+ <transparent opaque="A_ONE">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ <index_of_refraction>
+ <float>1</float>
+ </index_of_refraction>
+ </phong>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ </library_effects>
+
+
+ <library_geometries>
+ <geometry id="F1" name="default_physics_shape">
+ <mesh>
+
+ <source id="cube-vertex-positions">
+ <float_array id="ID2-array" count="72">-0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 </float_array>
+ <technique_common>
+ <accessor source="#ID2-array" count="24" stride="3">
+ <param name="X" type="float"/>
+ <param name="Y" type="float"/>
+ <param name="Z" type="float"/>
+ </accessor>
+ </technique_common>
+ </source>
+
+ <vertices id="cube-vertices">
+ <input semantic="POSITION" source="#cube-vertex-positions"/>
+ </vertices>
+
+ <triangles count="12" material="geometryElement5">
+ <input semantic="VERTEX" offset="0" source="#cube-vertices"/>
+ <p>0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23 </p>
+ </triangles>
+
+ </mesh>
+ </geometry>
+ </library_geometries>
+ <library_visual_scenes>
+
+
+ <visual_scene id="reportScene">
+ <!-- No Spaces allowed in Name -->
+ <node id="F1" name="Face1">
+ <instance_geometry url="#F1">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="geometryElement5" target="#Blue"/>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ </node>
+ </visual_scene>
+ </library_visual_scenes>
+
+
+ <scene>
+ <instance_visual_scene url="#reportScene"/>
+ </scene>
+
+
+</COLLADA>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index e04e38b9de..efd498183d 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 34
+version 40
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -28,7 +28,7 @@ version 34
//
list all
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
+RenderAvatarCloth 0 0
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
@@ -46,22 +46,24 @@ RenderGround 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 4
+RenderTransparentWater 1 1
+RenderReflectionProbeDetail 1 2
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVBOEnable 1 1
RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
-UseOcclusion 1 1
+UseOcclusion 1 0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
+RenderPBR 1 1
+RenderReflectionProbeCount 1 256
RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
@@ -78,7 +80,6 @@ RenderGLMultiThreaded 1 1
//
list Low
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -88,15 +89,12 @@ RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
RenderLocalLights 1 0
RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 0
+RenderReflectionProbeDetail 1 -1
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
-RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
@@ -108,7 +106,6 @@ RenderFSAASamples 1 0
//
list LowMid
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -116,16 +113,13 @@ RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
RenderMaxPartCount 1 2048
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 0
+RenderReflectionProbeDetail 1 -1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
@@ -137,7 +131,6 @@ RenderFSAASamples 1 0
//
list Mid
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -145,28 +138,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 0
//
// Medium High Graphics Settings (deferred enabled)
//
list MidHigh
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -174,28 +163,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// High Graphics Settings (deferred + SSAO)
//
list High
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -203,28 +188,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// High Ultra Graphics Settings (deferred + SSAO + shadows)
//
list HighUltra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -232,28 +213,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 256
@@ -261,8 +238,6 @@ RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderLocalLights 1 1
RenderMaxPartCount 1 8192
-RenderObjectBump 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -270,18 +245,17 @@ RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// Class Unknown Hardware (unknown)
//
list Unknown
RenderShadowDetail 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
@@ -296,29 +270,26 @@ RenderCompressTextures 1 0
//
list safe
RenderAnisotropic 1 0
-RenderAvatarCloth 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
-RenderObjectBump 0 0
RenderLocalLights 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
+RenderTransparentWater 1 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
+RenderReflectionProbeDetail 0 -1
list Intel
RenderAnisotropic 1 0
RenderFSAASamples 1 0
RenderGLMultiThreaded 1 0
-RenderGLContextCoreProfile 1 0
+RenderGLContextCoreProfile 1 0
-// AMD cards generally perform better when not using VBOs for streaming data
-// AMD cards also prefer an OpenGL Compatibility Profile Context
+// HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 32
list AMD
-RenderUseStreamVBO 1 0
-RenderGLContextCoreProfile 1 0
-
+RenderReflectionProbeCount 1 32
+list GL3
+RenderFSAASamples 0 0
+RenderReflectionProbeDetail 0 -1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index d319d26e1f..d40e7aff0b 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 38
+version 41
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -28,7 +28,7 @@ version 38
//
list all
RenderAnisotropic 1 0
-RenderAvatarCloth 1 1
+RenderAvatarCloth 0 0
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
@@ -46,7 +46,6 @@ RenderGround 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -55,7 +54,7 @@ RenderVBOEnable 1 1
RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
-UseOcclusion 1 1
+UseOcclusion 1 0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
@@ -63,21 +62,22 @@ Disregard96DefaultDrawDistance 1 1
RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
+RenderPBR 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
-RenderGLContextCoreProfile 1 0
+RenderGLContextCoreProfile 1 1
RenderGLMultiThreaded 1 0
+RenderReflectionProbeDetail 1 2
//
// Low Graphics Settings
//
list Low
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -87,27 +87,23 @@ RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
RenderLocalLights 1 0
RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 0.5
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
+RenderReflectionProbeDetail 1 -1
//
// Medium Low Graphics Settings
//
list LowMid
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -115,28 +111,24 @@ RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
RenderMaxPartCount 1 2048
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
+RenderReflectionProbeDetail 1 -1
//
// Medium Graphics Settings (standard)
//
list Mid
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -144,28 +136,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 0
//
// Medium High Graphics Settings (deferred enabled)
//
list MidHigh
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -173,28 +161,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 0
//
// High Graphics Settings (deferred + SSAO)
//
list High
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -202,28 +186,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// High Ultra Graphics Settings (deferred + SSAO + shadows)
//
list HighUltra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -231,28 +211,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
RenderUseAdvancedAtmospherics 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 256
@@ -260,8 +236,6 @@ RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderLocalLights 1 1
RenderMaxPartCount 1 8192
-RenderObjectBump 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -269,18 +243,17 @@ RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// Class Unknown Hardware (unknown)
//
list Unknown
RenderShadowDetail 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
@@ -296,16 +269,11 @@ RenderCompressTextures 1 0
//
list safe
RenderAnisotropic 1 0
-RenderAvatarCloth 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
-RenderObjectBump 0 0
RenderLocalLights 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
@@ -321,6 +289,6 @@ RenderAnisotropic 1 0
RenderLocalLights 1 0
RenderFSAASamples 1 0
-list OSX_10_6_8
-RenderDeferred 0 0
-
+list GL3
+RenderFSAASamples 0 0
+RenderReflectionProbeDetail 0 -1
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 7513908cb4..60e26274cb 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -351,11 +351,29 @@ DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp"
DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage"
ClearErrors
+INSTALL_FILES_START:
+
Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer
# This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
%%INSTALL_FILES%%
+IfErrors 0 INSTALL_FILES_DONE
+ StrCmp $SKIP_DIALOGS "true" INSTALL_FILES_DONE
+ MessageBox MB_ABORTRETRYIGNORE $(ErrorSecondLifeInstallRetry) IDABORT INSTALL_FILES_CANCEL IDRETRY INSTALL_FILES_START
+ # MB_ABORTRETRYIGNORE does not accept IDIGNORE
+ Goto INSTALL_FILES_DONE
+
+INSTALL_FILES_CANCEL:
+ # We are quiting, cleanup.
+ # Silence warnings from RemoveProgFilesOnInst.
+ StrCpy $SKIP_DIALOGS "true"
+ Call RemoveProgFilesOnInst
+ MessageBox MB_OK $(ErrorSecondLifeInstallSupport)
+ Quit
+
+INSTALL_FILES_DONE:
+
# Pass the installer's language to the client to use as a default
StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)"
@@ -622,7 +640,9 @@ Function RemoveProgFilesOnInst
Push $0
StrCpy $0 0
-PREINSTALLREMOVE:
+ClearErrors
+
+PREINSTALL_REMOVE:
# Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575
Delete "$INSTDIR\$INSTEXE"
@@ -642,17 +662,17 @@ RMDir /r "$INSTDIR\llplugin"
IntOp $0 $0 + 1
-IfErrors 0 PREINSTALLDONE
- IntCmp $0 1 PREINSTALLREMOVE #try again once
- StrCmp $SKIP_DIALOGS "true" PREINSTALLDONE
- MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALLFAIL IDRETRY PREINSTALLREMOVE
+IfErrors 0 PREINSTALL_DONE
+ IntCmp $0 1 PREINSTALL_REMOVE #try again once
+ StrCmp $SKIP_DIALOGS "true" PREINSTALL_DONE
+ MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALL_FAIL IDRETRY PREINSTALL_REMOVE
# MB_ABORTRETRYIGNORE does not accept IDIGNORE
- Goto PREINSTALLDONE
+ Goto PREINSTALL_DONE
-PREINSTALLFAIL:
+PREINSTALL_FAIL:
Quit
-PREINSTALLDONE:
+PREINSTALL_DONE:
# We are no longer including release notes with the viewer, so remove them.
Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk"
diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index 648ddbfb85..73f23086be 100644
--- a/indra/newview/installers/windows/lang_da.nsi
+++ b/indra/newview/installers/windows/lang_da.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 188c30197a..7cc70e4c76 100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
@@ -73,6 +73,10 @@ LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Second Life kann nicht entfer
; CheckNetworkConnection
LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..."
+; error during installation
+LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life konnte nicht korrekt installiert werden, einige Dateien wurden eventuell nicht korrekt von der Installationroutine kopiert."
+LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Bitte laden Sie den Viewer erneut von https://secondlife.com/support/downloads/ und versuchen Sie die Installation erneut. Sollte das Problem weiterhin bestehen, dann kontaktieren Sie unseren Support unter https://support.secondlife.com."
+
; ask to remove user's data files
LangString RemoveDataFilesMB ${LANG_GERMAN} "Möchten Sie alle anderen zu Second Life gehörigen Dateien ebenfalls ENTFERNEN?$\n$\nWir empfehlen, die Einstellungen und Cache-Dateien zu behalten, wenn Sie andere Versionen von Second Life installiert haben oder eine Deinstallation durchführen, um Second Life auf eine neuere Version zu aktualisieren."
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 0639d51e10..2eaf97d023 100644
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index ee30651a38..364cc9f67e 100755
--- a/indra/newview/installers/windows/lang_es.nsi
+++ b/indra/newview/installers/windows/lang_es.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 7cd90ec314..2f34c0c87a 100755
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index 194062da9a..51214d3a9c 100755
--- a/indra/newview/installers/windows/lang_it.nsi
+++ b/indra/newview/installers/windows/lang_it.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index a54005ba14..296703d1a3 100755
--- a/indra/newview/installers/windows/lang_ja.nsi
+++ b/indra/newview/installers/windows/lang_ja.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 355d806866..299645bbb7 100644
--- a/indra/newview/installers/windows/lang_pl.nsi
+++ b/indra/newview/installers/windows/lang_pl.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index 97f5d2b44a..542c8654b5 100755
--- a/indra/newview/installers/windows/lang_pt-br.nsi
+++ b/indra/newview/installers/windows/lang_pt-br.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index 65a9f4846d..4e53a4957d 100755
--- a/indra/newview/installers/windows/lang_ru.nsi
+++ b/indra/newview/installers/windows/lang_ru.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index e71886cc66..bae5029ad1 100755
--- a/indra/newview/installers/windows/lang_tr.nsi
+++ b/indra/newview/installers/windows/lang_tr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index f5f0c6cbdf..7922d9df52 100755
--- a/indra/newview/installers/windows/lang_zh.nsi
+++ b/indra/newview/installers/windows/lang_zh.nsi
Binary files differ
diff --git a/indra/newview/licenses-mac.txt b/indra/newview/licenses-mac.txt
index fba6a55da3..29b5a919bd 100644
--- a/indra/newview/licenses-mac.txt
+++ b/indra/newview/licenses-mac.txt
@@ -719,3 +719,55 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+
+
+============
+tinygltf
+============
+MIT License
+
+Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+==============
+Vulkan GLTF
+==============
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt
index 837d92139d..eddc9a4475 100644
--- a/indra/newview/licenses-win32.txt
+++ b/indra/newview/licenses-win32.txt
@@ -796,3 +796,52 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+============
+tinygltf
+============
+MIT License
+
+Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+==============
+Vulkan GLTF
+==============
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index b79af04c36..5250369813 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -96,6 +96,7 @@
#include "stringize.h"
#include "boost/foreach.hpp"
#include "llcorehttputil.h"
+#include "lluiusage.h"
using namespace LLAvatarAppearanceDefines;
@@ -574,6 +575,8 @@ void LLAgent::ageChat()
//-----------------------------------------------------------------------------
void LLAgent::moveAt(S32 direction, bool reset)
{
+ LLUIUsage::instance().logCommand("Agent.MoveAt");
+
mMoveTimer.reset();
LLFirstUse::notMoving(false);
@@ -713,6 +716,15 @@ void LLAgent::moveYaw(F32 mag, bool reset_view)
setControlFlags(AGENT_CONTROL_YAW_NEG);
}
+ U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
+ if ((getControlFlags() & mask) == mask)
+ {
+ // Rotation into both directions should cancel out
+ // But keep sending controls to simulator,
+ // it's needed for script based controls
+ gAgentCamera.setYawKey(0);
+ }
+
if (reset_view)
{
gAgentCamera.resetView();
@@ -2005,6 +2017,27 @@ void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32
//
gAgentCamera.updateLookAt(mouse_x, mouse_y);
+
+ // When agent has no parents, position updates come from setPositionAgent()
+ // But when agent has a parent (ex: is seated), position remains unchanged
+ // relative to parent and no parent's position update trigger
+ // setPositionAgent().
+ // But EEP's sky track selection still needs an update if agent has a parent
+ // and parent moves (ex: vehicles).
+ if (isAgentAvatarValid()
+ && gAgentAvatarp->getParent()
+ && !mOnPositionChanged.empty()
+ )
+ {
+ LLVector3d new_position = getPositionGlobal();
+ if ((mLastTestGlobal - new_position).lengthSquared() > 1.0)
+ {
+ // If the position has changed by more than 1 meter since the last time we triggered.
+ // filters out some noise.
+ mLastTestGlobal = new_position;
+ mOnPositionChanged(mFrameAgent.getOrigin(), new_position);
+ }
+ }
}
// friends and operators
@@ -3996,6 +4029,7 @@ void LLAgent::startTeleportRequest()
}
if (hasPendingTeleportRequest())
{
+ LLUIUsage::instance().logCommand("Agent.StartTeleportRequest");
mTeleportCanceled.reset();
if (!isMaturityPreferenceSyncedWithServer())
{
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 84a41113be..57a59d81c4 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -401,10 +401,9 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
LLQuaternion obj_rot = object->getRenderRotation();
LLVector3 obj_pos = object->getRenderPosition();
- BOOL is_avatar = object->isAvatar();
// if is avatar - don't do any funk heuristics to position the focal point
// see DEV-30589
- if (is_avatar)
+ if (object->isAvatar() || (object->isAnimatedObject() && object->getControlAvatar()))
{
return original_focus_point - obj_pos;
}
@@ -529,7 +528,6 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
// or keep the focus point in the object middle when (relatively) far
// NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars
// is almost always "tumble about middle" and not "spin around surface point"
- if (!is_avatar)
{
LLVector3 obj_rel = original_focus_point - object->getRenderPosition();
@@ -1188,12 +1186,18 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
static LLTrace::BlockTimerStatHandle FTM_UPDATE_CAMERA("Camera");
+extern BOOL gCubeSnapshot;
+
//-----------------------------------------------------------------------------
// updateCamera()
//-----------------------------------------------------------------------------
void LLAgentCamera::updateCamera()
{
LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA);
+ if (gCubeSnapshot)
+ {
+ return;
+ }
// - changed camera_skyward to the new global "mCameraUpVector"
mCameraUpVector = LLVector3::z_axis;
@@ -1417,7 +1421,7 @@ void LLAgentCamera::updateCamera()
F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
- if (!mFocusObject) // we differentiate on avatar mode
+ if (mFocusOnAvatar && !mFocusObject) // we differentiate on avatar mode
{
// for avatar-relative focus, we smooth in avatar space -
// the avatar moves too jerkily w/r/t global space to smooth there.
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index f981e08ff7..21df036cb7 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -74,10 +74,10 @@ public:
void decrementNumberOfPicks() { --mNumberOfPicks; }
-private:
-
void onServerRespond(LLAvatarPicks* picks);
+private:
+
/**
* Sets number of Picks.
*/
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index be168ff5dd..2e769dc737 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -37,6 +37,7 @@
#include "llgesturemgr.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lllocaltextureobject.h"
@@ -1582,6 +1583,14 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
+ if (!item->isFinished())
+ {
+ LL_WARNS() << "Tried to edit wearable that isn't loaded" << LL_ENDL;
+ // Restart fetch or put item to the front
+ LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false);
+ return;
+ }
+
LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
if (!wearable)
{
@@ -1595,6 +1604,18 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
+ S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE);
+ S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR);
+ S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES);
+ S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN);
+ if (!shape_count || !hair_count || !eye_count || !skin_count)
+ {
+ // Don't let user edit wearables if avatar is cloud due to missing parts.
+ // Let user edit wearables if avatar is cloud due to missing textures.
+ LL_WARNS() << "Cannot modify wearable. Avatar is cloud and missing parts." << LL_ENDL;
+ return;
+ }
+
const BOOL disable_camera_switch = LLWearableType::getInstance()->getDisableCameraSwitch(wearable->getType());
LLPanel* panel = LLFloaterSidePanelContainer::getPanel("appearance");
LLSidepanelAppearance::editWearable(wearable, panel, disable_camera_switch);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 39c9fa1bca..909f32cd21 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -60,6 +60,7 @@
#include "llappviewer.h"
#include "llcoros.h"
#include "lleventcoro.h"
+#include "lluiusage.h"
#include "llavatarpropertiesprocessor.h"
@@ -1426,6 +1427,9 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
bool replace,
LLPointer<LLInventoryCallback> cb)
{
+ LL_DEBUGS("UIUsage") << "wearItemsOnAvatar" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.WearItem");
+
bool first = true;
LLInventoryObject::const_object_list_t items_to_link;
@@ -2761,6 +2765,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
<< "'" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.WearCategory");
if (gAgentCamera.cameraCustomizeAvatar())
{
@@ -3968,6 +3973,8 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo
{
if (!isAgentAvatarValid()) return;
+ LLUIUsage::instance().logCommand("Avatar.CreateNewOutfit");
+
LL_DEBUGS("Avatar") << "creating new outfit" << LL_ENDL;
gAgentWearables.notifyLoadingStarted();
@@ -4006,6 +4013,9 @@ void LLAppearanceMgr::wearBaseOutfit()
void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
{
+ LL_DEBUGS("UIUsage") << "removeItemsFromAvatar" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.RemoveItem");
+
if (ids_to_remove.empty())
{
LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL;
@@ -4485,6 +4495,8 @@ public:
"Quick Appearance");
if ( gInventory.getCategory( folder_uuid ) != NULL )
{
+ // Assume this is coming from the predefined avatars web floater
+ LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance");
LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 55c0b31bf6..66316a18d4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -338,9 +338,6 @@ LLFrameTimer gRestoreGLTimer;
BOOL gRestoreGL = FALSE;
bool gUseWireframe = FALSE;
-//use for remember deferred mode in wireframe switch
-bool gInitialDeferredModeForWireframe = FALSE;
-
LLMemoryInfo gSysMemory;
U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp
@@ -531,7 +528,7 @@ static void settings_to_globals()
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
- LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
+ LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
@@ -556,7 +553,7 @@ static void settings_to_globals()
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
- LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
+ LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
#if LL_DARWIN
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
@@ -566,12 +563,12 @@ static void settings_to_globals()
static void settings_modify()
{
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
- LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderBump = TRUE; // FALSE is deprecated -- gSavedSettings.getBOOL("RenderObjectBump");
+ LLPipeline::sRenderDeferred = TRUE; // FALSE is deprecated -- LLPipeline::sRenderBump&& gSavedSettings.getBOOL("RenderDeferred");
LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred;
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; // square lod factor to get exponential range of [1,4]
- gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
+ gDebugGL = gDebugGLSession || gDebugSession;
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
}
@@ -1124,7 +1121,8 @@ bool LLAppViewer::init()
gGLActive = FALSE;
#if LL_RELEASE_FOR_DOWNLOAD
- if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
+ // Skip updater if this is a non-interactive instance
+ if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive)
{
LLProcess::Params updater;
updater.desc = "updater process";
@@ -1448,6 +1446,8 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
+ // if one of our coroutines threw an uncaught exception, rethrow it now
+ LLCoros::instance().rethrow();
}
if (!LLApp::isExiting())
@@ -1505,22 +1505,23 @@ bool LLAppViewer::doFrame()
// Render scene.
// *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
- if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Display" )
- pingMainloopTimeout("Main:Display");
- gGLActive = TRUE;
+ if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Display");
+ pingMainloopTimeout("Main:Display");
+ gGLActive = TRUE;
- display();
+ display();
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
- pingMainloopTimeout("Main:Snapshot");
- LLFloaterSnapshot::update(); // take snapshots
- LLFloaterOutfitSnapshot::update();
- gGLActive = FALSE;
- }
- }
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot");
+ pingMainloopTimeout("Main:Snapshot");
+ gPipeline.mReflectionMapManager.update();
+ LLFloaterSnapshot::update(); // take snapshots
+ LLFloaterOutfitSnapshot::update();
+ gGLActive = FALSE;
+ }
+ }
}
{
@@ -2052,7 +2053,6 @@ bool LLAppViewer::cleanup()
}
sTextureFetch->shutDownTextureCacheThread() ;
- sTextureFetch->shutDownImageDecodeThread() ;
LLLFSThread::sLocal->shutdown();
LL_INFOS() << "Shutting down message system" << LL_ENDL;
@@ -2067,8 +2067,13 @@ bool LLAppViewer::cleanup()
//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
delete sTextureCache;
sTextureCache = NULL;
- delete sTextureFetch;
- sTextureFetch = NULL;
+ if (sTextureFetch)
+ {
+ sTextureFetch->shutdown();
+ sTextureFetch->waitOnPending();
+ delete sTextureFetch;
+ sTextureFetch = NULL;
+ }
delete sImageDecodeThread;
sImageDecodeThread = NULL;
delete mFastTimerLogThread;
@@ -2182,11 +2187,23 @@ bool LLAppViewer::initThreads()
LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo
+ //auto configure thread count
+ LLSD threadCounts = gSavedSettings.getLLSD("ThreadPoolSizes");
+
+ // get the number of concurrent threads that can run
+ S32 cores = std::thread::hardware_concurrency();
+
+ // The only configurable thread count right now is ImageDecode
+ // The viewer typically starts around 8 threads not including image decode,
+ // so try to leave at least one core free
+ S32 image_decode_count = llclamp(cores - 9, 1, 8);
+ threadCounts["ImageDecode"] = image_decode_count;
+ gSavedSettings.setLLSD("ThreadPoolSizes", threadCounts);
+
// Image decoding
LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(),
- sImageDecodeThread,
enable_threads && true,
app_metrics_qa_mode);
LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread();
@@ -2469,10 +2486,24 @@ bool LLAppViewer::initConfiguration()
//Load settings files list
std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
LLXMLNodePtr root;
- BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
+ BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
if (!success)
{
- LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ if (gDirUtilp->fileExists(settings_file_list))
+ {
+ LL_ERRS() << "Cannot load default configuration file settings_files.xml. "
+ << "Please reinstall viewer from https://secondlife.com/support/downloads/ "
+ << "and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_ERRS() << "Default configuration file settings_files.xml not found. "
+ << "Please reinstall viewer from https://secondlife.com/support/downloads/ "
+ << "and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
}
mSettingsLocationList = new SettingsFiles();
@@ -2695,19 +2726,14 @@ bool LLAppViewer::initConfiguration()
if (clp.hasOption("graphicslevel"))
{
- // User explicitly requested --graphicslevel on the command line. We
- // expect this switch has already set RenderQualityPerformance. Check
- // that value for validity.
- U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance");
- if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel))
- {
- // graphicslevel is valid: save it and engage it later. Capture
- // the requested value separately from the settings variable
- // because, if this is the first run, LLViewerWindow's constructor
- // will call LLFeatureManager::applyRecommendedSettings(), which
- // overwrites this settings variable!
- mForceGraphicsLevel = graphicslevel;
- }
+ // User explicitly requested --graphicslevel on the command line. We
+ // expect this switch has already set RenderQualityPerformance. Check
+ // that value for validity later.
+ // Capture the requested value separately from the settings variable
+ // because, if this is the first run, LLViewerWindow's constructor
+ // will call LLFeatureManager::applyRecommendedSettings(), which
+ // overwrites this settings variable!
+ mForceGraphicsLevel = gSavedSettings.getU32("RenderQualityPerformance");
}
LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
@@ -2721,6 +2747,15 @@ bool LLAppViewer::initConfiguration()
ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
}
+ if (gSavedSettings.getBOOL("RenderDebugGLSession"))
+ {
+ gDebugGLSession = TRUE;
+ gDebugGL = TRUE;
+ // gDebugGL can cause excessive logging
+ // so it's limited to a single session
+ gSavedSettings.setBOOL("RenderDebugGLSession", FALSE);
+ }
+
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
{
@@ -3056,7 +3091,7 @@ bool LLAppViewer::initWindow()
// Initialize GL stuff
//
- if (mForceGraphicsLevel)
+ if (mForceGraphicsLevel && (LLFeatureManager::instance().isValidGraphicsLevel(*mForceGraphicsLevel)))
{
LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
@@ -3117,6 +3152,11 @@ bool LLAppViewer::isUpdaterMissing()
return mUpdaterNotFound;
}
+bool LLAppViewer::waitForUpdater()
+{
+ return !gSavedSettings.getBOOL("CmdLineSkipUpdater") && !mUpdaterNotFound && !gNonInteractive;
+}
+
void LLAppViewer::writeDebugInfo(bool isStatic)
{
#if LL_WINDOWS && LL_BUGSPLAT
@@ -3197,7 +3237,28 @@ LLSD LLAppViewer::getViewerInfo() const
info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER)));
#if LL_WINDOWS
- std::string drvinfo = gDXHardware.getDriverVersionWMI();
+ std::string drvinfo;
+
+ if (gGLManager.mIsIntel)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_INTEL);
+ }
+ else if (gGLManager.mIsNVIDIA)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_NVIDIA);
+ }
+ else if (gGLManager.mIsAMD)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_AMD);
+ }
+
+ if (drvinfo.empty())
+ {
+ // Generic/substitute windows driver? Unknown vendor?
+ LL_WARNS("DriverVersion") << "Vendor based driver search failed, searching for any driver" << LL_ENDL;
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_ANY);
+ }
+
if (!drvinfo.empty())
{
info["GRAPHICS_DRIVER_VERSION"] = drvinfo;
@@ -3240,9 +3301,18 @@ LLSD LLAppViewer::getViewerInfo() const
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined";
if(LLVoiceClient::getInstance()->voiceEnabled())
{
- LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ const std::string build_version = version.mBuildVersion;
std::ostringstream version_string;
- version_string << version.serverType << " " << version.serverVersion << std::endl;
+ if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(),
+ version.serverVersion.begin()))
+ { // Normal case: Show type and build version.
+ version_string << version.serverType << " " << build_version << std::endl;
+ }
+ else
+ { // Mismatch: Show both versions.
+ version_string << version.serverVersion << "/" << build_version << std::endl;
+ }
info["VOICE_VERSION"] = version_string.str();
}
else
@@ -3435,7 +3505,7 @@ void LLAppViewer::cleanupSavedSettings()
}
}
- gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale );
+ gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting());
// Some things are cached in LLAgent.
if (gAgent.isInitialized())
@@ -4206,6 +4276,15 @@ U32 LLAppViewer::getTextureCacheVersion()
}
//static
+U32 LLAppViewer::getDiskCacheVersion()
+{
+ // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes.
+ const U32 DISK_CACHE_VERSION = 1;
+
+ return DISK_CACHE_VERSION ;
+}
+
+//static
U32 LLAppViewer::getObjectCacheVersion()
{
// Viewer object cache version, change if object update
@@ -4225,21 +4304,30 @@ bool LLAppViewer::initCache()
// initialize the new disk cache using saved settings
const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");
+ const U32 MB = 1024 * 1024;
+ const uintmax_t MIN_CACHE_SIZE = 256 * MB;
+ const uintmax_t MAX_CACHE_SIZE = 9984ll * MB;
+ const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB;
+ const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
+ const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
+ const F64 texture_cache_percent = 100.0 - disk_cache_percent;
+
// note that the maximum size of this cache is defined as a percentage of the
// total cache size - the 'CacheSize' pref - for all caches.
- const unsigned int cache_total_size_mb = gSavedSettings.getU32("CacheSize");
- const double disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
- const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100;
- const uintmax_t disk_cache_bytes = disk_cache_mb * 1024 * 1024;
+ const uintmax_t disk_cache_size = uintmax_t(cache_total_size * disk_cache_percent / 100);
const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
bool texture_cache_mismatch = false;
+ bool remove_vfs_files = false;
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
texture_cache_mismatch = true;
if(!read_only)
{
gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
+
+ //texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed
+ remove_vfs_files = true;
}
}
@@ -4281,11 +4369,23 @@ bool LLAppViewer::initCache()
}
const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
- LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info);
+ LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info);
if (!read_only)
{
- if (mPurgeCache)
+ if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion())
+ {
+ LLDiskCache::getInstance()->clearCache();
+ remove_vfs_files = true;
+ gSavedSettings.setS32("DiskCacheVersion", LLAppViewer::getDiskCacheVersion());
+ }
+
+ if (remove_vfs_files)
+ {
+ LLDiskCache::getInstance()->removeOldVFSFiles();
+ }
+
+ if (mPurgeCache)
{
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
@@ -4304,22 +4404,14 @@ bool LLAppViewer::initCache()
LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
// Init the texture cache
- // Allocate 80% of the cache size for textures
- const S32 MB = 1024 * 1024;
- const S64 MIN_CACHE_SIZE = 256 * MB;
- const S64 MAX_CACHE_SIZE = 9984ll * MB;
-
- S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
- cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
+ // Allocate the remaining percent which is not allocated to the disk cache
+ const S64 texture_cache_size = S64(cache_total_size * texture_cache_percent / 100);
- S64 texture_cache_size = cache_size;
-
- S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
- texture_cache_size -= extra;
+ LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
- return true;
+ return true;
}
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
@@ -4812,13 +4904,18 @@ void LLAppViewer::idle()
}
}
+
+ // Update layonts, handle mouse events, tooltips, e t c
+ // updateUI() needs to be called even in case viewer disconected
+ // since related notification still needs handling and allows
+ // opening chat.
+ gViewerWindow->updateUI();
+
if (gDisconnected)
{
return;
}
- gViewerWindow->updateUI();
-
if (gTeleportDisplay)
{
return;
@@ -4996,8 +5093,7 @@ void LLAppViewer::idle()
audio_update_wind(false);
// this line actually commits the changes we've made to source positions, etc.
- const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
- gAudiop->idle(max_audio_decode_time);
+ gAudiop->idle();
}
}
@@ -5358,7 +5454,7 @@ void LLAppViewer::disconnectViewer()
gFloaterView->restoreAll();
}
- if (LLSelectMgr::getInstance())
+ if (LLSelectMgr::instanceExists())
{
LLSelectMgr::getInstance()->deselectAll();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 68c04d450b..3888fa8ae3 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -106,6 +106,7 @@ public:
bool logoutRequestSent() { return mLogoutRequestSent; }
bool isSecondInstance() { return mSecondInstance; }
bool isUpdaterMissing(); // In use by tests
+ bool waitForUpdater();
void writeDebugInfo(bool isStatic=true);
@@ -129,6 +130,7 @@ public:
static U32 getTextureCacheVersion() ;
static U32 getObjectCacheVersion() ;
+ static U32 getDiskCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
@@ -152,16 +154,16 @@ public:
void removeMarkerFiles();
void removeDumpDir();
- // LLAppViewer testing helpers.
- // *NOTE: These will potentially crash the viewer. Only for debugging.
- virtual void forceErrorLLError();
- virtual void forceErrorBreakpoint();
- virtual void forceErrorBadMemoryAccess();
- virtual void forceErrorInfiniteLoop();
- virtual void forceErrorSoftwareException();
- virtual void forceErrorDriverCrash();
- virtual void forceErrorCoroutineCrash();
- virtual void forceErrorThreadCrash();
+ // LLAppViewer testing helpers.
+ // *NOTE: These will potentially crash the viewer. Only for debugging.
+ virtual void forceErrorLLError();
+ virtual void forceErrorBreakpoint();
+ virtual void forceErrorBadMemoryAccess();
+ virtual void forceErrorInfiniteLoop();
+ virtual void forceErrorSoftwareException();
+ virtual void forceErrorDriverCrash();
+ virtual void forceErrorCoroutineCrash();
+ virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
@@ -390,7 +392,6 @@ extern BOOL gDisconnected;
extern LLFrameTimer gRestoreGLTimer;
extern BOOL gRestoreGL;
extern bool gUseWireframe;
-extern bool gInitialDeferredModeForWireframe;
extern LLMemoryInfo gSysMemory;
extern U64Bytes gMemoryAllocated;
diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp
index 4b6c855bde..1846238d93 100644
--- a/indra/newview/llaudiosourcevo.cpp
+++ b/indra/newview/llaudiosourcevo.cpp
@@ -34,6 +34,7 @@
#include "llmutelist.h"
#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
+#include "llvoavatarself.h"
LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp)
: LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX),
@@ -141,11 +142,36 @@ void LLAudioSourceVO::updateMute()
LLVector3d pos_global = getPosGlobal();
F32 cutoff = mObjectp->getSoundCutOffRadius();
- if ((cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff)) // consider cutoff below 0.1m as off
- || !LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
- {
- mute = true;
- }
+ // Object can specify radius at which it turns off
+ // consider cutoff below 0.1m as 'cutoff off'
+ if (cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff))
+ {
+ mute = true;
+ }
+ // check if parcel allows sounds to pass border
+ else if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
+ {
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ // Check if agent is riding this object
+ // Agent can ride something out of region border and canHearSound
+ // will treat object as not being part of agent's parcel.
+ LLViewerObject *sound_root = (LLViewerObject*)mObjectp->getRoot();
+ LLViewerObject *agent_root = (LLViewerObject*)gAgentAvatarp->getRoot();
+ if (sound_root != agent_root)
+ {
+ mute = true;
+ }
+ else
+ {
+ LL_INFOS() << "roots identical" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mute = true;
+ }
+ }
if (!mute)
{
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 1797d2dd6e..3e450e6dec 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -48,6 +48,7 @@
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llfloaterpay.h"
+#include "llfloaterprofile.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterwebcontent.h"
#include "llfloaterworldmap.h"
@@ -62,11 +63,14 @@
#include "llnotificationsutil.h" // for LLNotificationsUtil
#include "llpaneloutfitedit.h"
#include "llpanelprofile.h"
+#include "llparcel.h"
#include "llrecentpeople.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
+#include "llviewernetwork.h" //LLGridManager
+#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lltrans.h"
#include "llcallingcard.h"
@@ -74,6 +78,7 @@
#include "llsidepanelinventory.h"
#include "llavatarname.h"
#include "llagentui.h"
+#include "lluiusage.h"
// Flags for kick message
const U32 KICK_FLAGS_DEFAULT = 0x0;
@@ -81,6 +86,19 @@ const U32 KICK_FLAGS_FREEZE = 1 << 0;
const U32 KICK_FLAGS_UNFREEZE = 1 << 1;
+std::string getProfileURL(const std::string& agent_name, bool feed_only)
+{
+ std::string url = "[WEB_PROFILE_URL][AGENT_NAME][FEED_ONLY]";
+ LLSD subs;
+ subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
+ subs["AGENT_NAME"] = agent_name;
+ subs["FEED_ONLY"] = feed_only ? "/?feed_only=true" : "";
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLStringUtil::toLower(url);
+ return url;
+}
+
+
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
{
@@ -96,7 +114,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin
payload["id"] = id;
payload["name"] = name;
- LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
+ LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
// add friend to recent people list
LLRecentPeople::instance().add(id);
@@ -316,57 +334,144 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
make_ui_sound("UISndStartIM");
}
-static const char* get_profile_floater_name(const LLUUID& avatar_id)
+// static
+void LLAvatarActions::showProfile(const LLUUID& avatar_id)
{
- // Use different floater XML for our profile to be able to save its rect.
- return avatar_id == gAgentID ? "my_profile" : "profile";
+ if (avatar_id.notNull())
+ {
+ LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
+ }
}
-static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
+// static
+void LLAvatarActions::showPicks(const LLUUID& avatar_id)
{
- std::string url = getProfileURL(av_name.getAccountName());
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick();
+ }
+ }
+}
- // PROFILES: open in webkit window
- LLFloaterWebContent::Params p;
- p.url(url).id(agent_id.asString());
- LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
+// static
+void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick(pick_id);
+ }
+ }
+}
+
+// static
+void LLAvatarActions::createPick()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ LLViewerRegion* region = gAgent.getRegion();
+ if (profilefloater && region)
+ {
+ LLPickData data;
+ data.pos_global = gAgent.getPositionGlobal();
+ data.sim_name = region->getName();
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ data.name = parcel->getName();
+ data.desc = parcel->getDesc();
+ data.snapshot_id = parcel->getSnapshotID();
+ data.parcel_id = parcel->getID();
+ }
+ else
+ {
+ data.name = region->getName();
+ }
+
+ profilefloater->createPick(data);
+ }
}
// static
-void LLAvatarActions::showProfile(const LLUUID& id)
+bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)
{
- if (id.notNull())
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+ if (profilefloater)
+ {
+ return profilefloater->isPickTabSelected();
+ }
+ }
+ return false;
+}
+
+// static
+void LLAvatarActions::showClassifieds(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified();
+ }
+ }
+}
+
+// static
+void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit)
+{
+ if (avatar_id.notNull())
{
- LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified(classified_id, edit);
+ }
}
}
+// static
+void LLAvatarActions::createClassified()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ if (profilefloater)
+ {
+ profilefloater->createClassified();
+ }
+}
+
//static
-bool LLAvatarActions::profileVisible(const LLUUID& id)
+bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- return browser && browser->isShown();
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ return floater && floater->isShown();
}
//static
-LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id)
+LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)
{
- LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*>
- (LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id)));
- return browser;
+ LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+ return floater;
}
//static
-void LLAvatarActions::hideProfile(const LLUUID& id)
+void LLAvatarActions::hideProfile(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- if (browser)
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ if (floater)
{
- browser->closeFloater();
+ floater->closeFloater();
}
}
@@ -990,7 +1095,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
}
// static
-void LLAvatarActions::toggleBlock(const LLUUID& id)
+bool LLAvatarActions::toggleBlock(const LLUUID& id)
{
LLAvatarName av_name;
LLAvatarNameCache::get(id, &av_name);
@@ -1000,10 +1105,12 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
{
LLMuteList::getInstance()->remove(mute);
+ return false;
}
else
{
LLMuteList::getInstance()->add(mute);
+ return true;
}
}
@@ -1312,6 +1419,8 @@ bool LLAvatarActions::handleUnfreeze(const LLSD& notification, const LLSD& respo
void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
{
const LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+ LLUIUsage::instance().logCommand("Agent.SendFriendRequest");
+
send_improved_im(target_id,
target_name,
message,
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 7c721076c8..86183cc119 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -38,6 +38,8 @@ class LLInventoryPanel;
class LLFloater;
class LLView;
+std::string getProfileURL(const std::string& agent_name, bool feed_only = false);
+
/**
* Friend-related actions (add, remove, offer teleport, etc)
*/
@@ -91,13 +93,20 @@ public:
*/
static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
- /**
- * Show avatar profile.
- */
- static void showProfile(const LLUUID& id);
- static void hideProfile(const LLUUID& id);
- static bool profileVisible(const LLUUID& id);
- static LLFloater* getProfileFloater(const LLUUID& id);
+ /**
+ * Show avatar profile.
+ */
+ static void showProfile(const LLUUID& avatar_id);
+ static void showPicks(const LLUUID& avatar_id);
+ static void showPick(const LLUUID& avatar_id, const LLUUID& pick_id);
+ static void createPick();
+ static void showClassifieds(const LLUUID& avatar_id);
+ static void showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit = false);
+ static void createClassified();
+ static void hideProfile(const LLUUID& avatar_id);
+ static bool profileVisible(const LLUUID& avatar_id);
+ static bool isPickTabSelected(const LLUUID& avatar_id);
+ static LLFloater* getProfileFloater(const LLUUID& avatar_id);
/**
* Show avatar on world map.
@@ -126,9 +135,10 @@ public:
static void shareWithAvatars(LLView * panel);
/**
- * Block/unblock the avatar.
+ * Block/unblock the avatar by id.
+ * Returns true if blocked, returns false if unblocked
*/
- static void toggleBlock(const LLUUID& id);
+ static bool toggleBlock(const LLUUID& id);
/**
* Mute/unmute avatar.
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index b0715a3afd..c0990d9d11 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -241,21 +241,6 @@ void LLAvatarList::setDirty(bool val /*= true*/, bool force_refresh /*= false*/)
}
}
-void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name)
-{
- LL_DEBUGS("Avaline") << "Adding avaline item into the list: " << item_name << "|" << item_id << ", session: " << session_id << LL_ENDL;
- LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false);
- item->setAvatarId(item_id, session_id, true, false);
- item->setName(item_name);
- item->showLastInteractionTime(mShowLastInteractionTime);
- item->showSpeakingIndicator(mShowSpeakingIndicator);
- item->setOnline(false);
-
- addItem(item, item_id);
- mIDs.push_back(item_id);
- sort();
-}
-
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
@@ -296,18 +281,10 @@ void LLAvatarList::refresh()
{
// *NOTE: If you change the UI to show a different string,
// be sure to change the filter code below.
- if (LLRecentPeople::instance().isAvalineCaller(buddy_id))
- {
- const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id);
- addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString());
- }
- else
- {
- std::string display_name = getAvatarName(av_name);
- addNewItem(buddy_id,
- display_name.empty() ? waiting_str : display_name,
- LLAvatarTracker::instance().isBuddyOnline(buddy_id));
- }
+ std::string display_name = getAvatarName(av_name);
+ addNewItem(buddy_id,
+ display_name.empty() ? waiting_str : display_name,
+ LLAvatarTracker::instance().isBuddyOnline(buddy_id));
modified = true;
nadded++;
@@ -463,7 +440,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- if ( mContextMenu && !isAvalineItemSelected())
+ if ( mContextMenu)
{
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
@@ -523,21 +500,6 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
-bool LLAvatarList::isAvalineItemSelected()
-{
- std::vector<LLPanel*> selected_items;
- getSelectedItems(selected_items);
- std::vector<LLPanel*>::iterator it = selected_items.begin();
-
- for(; it != selected_items.end(); ++it)
- {
- if (dynamic_cast<LLAvalineListItem*>(*it))
- return true;
- }
-
- return false;
-}
-
void LLAvatarList::setVisible(BOOL visible)
{
if ( visible == FALSE && mContextMenu )
@@ -626,63 +588,3 @@ bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_
}
return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2);
}
-
-/************************************************************************/
-/* class LLAvalineListItem */
-/************************************************************************/
-LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarListItem(false)
-, mIsHideNumber(hide_number)
-{
- // should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called.
- buildFromFile( "panel_avatar_list_item.xml");
-}
-
-BOOL LLAvalineListItem::postBuild()
-{
- BOOL rv = LLAvatarListItem::postBuild();
-
- if (rv)
- {
- setOnline(true);
- showLastInteractionTime(false);
- setShowProfileBtn(false);
- setShowInfoBtn(false);
- mAvatarIcon->setValue("Avaline_Icon");
- mAvatarIcon->setToolTip(std::string(""));
- }
- return rv;
-}
-
-// to work correctly this method should be called AFTER setAvatarId for avaline callers with hidden phone number
-void LLAvalineListItem::setName(const std::string& name)
-{
- if (mIsHideNumber)
- {
- static U32 order = 0;
- typedef std::map<LLUUID, U32> avaline_callers_nums_t;
- static avaline_callers_nums_t mAvalineCallersNums;
-
- llassert(getAvatarId() != LLUUID::null);
-
- const LLUUID &uuid = getAvatarId();
-
- if (mAvalineCallersNums.find(uuid) == mAvalineCallersNums.end())
- {
- mAvalineCallersNums[uuid] = ++order;
- LL_DEBUGS("Avaline") << "Set name for new avaline caller: " << uuid << ", order: " << order << LL_ENDL;
- }
- LLStringUtil::format_map_t args;
- args["[ORDER]"] = llformat("%u", mAvalineCallersNums[uuid]);
- std::string hidden_name = LLTrans::getString("AvalineCaller", args);
-
- LL_DEBUGS("Avaline") << "Avaline caller: " << uuid << ", name: " << hidden_name << LL_ENDL;
- LLAvatarListItem::setAvatarName(hidden_name);
- LLAvatarListItem::setAvatarToolTip(hidden_name);
- }
- else
- {
- const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
- LLAvatarListItem::setAvatarName(formatted_phone);
- LLAvatarListItem::setAvatarToolTip(formatted_phone);
- }
-}
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 1a672c279b..48b0e70454 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -98,7 +98,6 @@ public:
virtual S32 notifyParent(const LLSD& info);
- void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name);
void handleDisplayNamesOptionChanged();
void setShowCompleteName(bool show) { mShowCompleteName = show;};
@@ -118,8 +117,6 @@ protected:
private:
- bool isAvalineItemSelected();
-
bool mIgnoreOnlineStatus;
bool mShowLastInteractionTime;
bool mDirty;
@@ -189,27 +186,4 @@ protected:
virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
};
-/**
- * Represents Avaline caller in Avatar list in Voice Control Panel and group chats.
- */
-class LLAvalineListItem : public LLAvatarListItem
-{
-public:
-
- /**
- * Constructor
- *
- * @param hide_number - flag indicating if number should be hidden.
- * In this case It will be shown as "Avaline Caller 1", "Avaline Caller 1", etc.
- */
- LLAvalineListItem(bool hide_number = true);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setName(const std::string& name);
-
-private:
- bool mIsHideNumber;
-};
-
#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index f41eb3daf4..dd0d06a8c8 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -36,6 +36,7 @@
#include "llstartup.h"
// Linden library includes
+#include "llavataractions.h" // for getProfileUrl
#include "lldate.h"
#include "lltrans.h"
#include "llui.h" // LLUI::getLanguage()
@@ -94,54 +95,98 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat
}
}
-
-void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
+void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
+ // this is the startup state when send_complete_agent_movement() message is sent.
+ // Before this messages won't work so don't bother trying
+ if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
+ {
+ return;
+ }
+
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+
// Suppress duplicate requests while waiting for a response from the network
if (isPendingRequest(avatar_id, type))
{
// waiting for a response, don't re-request
return;
}
- // indicate we're going to make a request
- addPendingRequest(avatar_id, type);
- std::vector<std::string> strings;
- strings.push_back( avatar_id.asString() );
- send_generic_message(method, strings);
+ std::string cap;
+
+ switch (type)
+ {
+ case APT_PROPERTIES:
+ // indicate we're going to make a request
+ sendAvatarPropertiesRequestMessage(avatar_id);
+ // can use getRegionCapability("AgentProfile"), but it is heavy
+ // initAgentProfileCapRequest(avatar_id, cap);
+ break;
+ case APT_PICKS:
+ case APT_GROUPS:
+ case APT_NOTES:
+ if (cap.empty())
+ {
+ // indicate we're going to make a request
+ sendGenericRequest(avatar_id, type, method);
+ }
+ else
+ {
+ initAgentProfileCapRequest(avatar_id, cap);
+ }
+ break;
+ default:
+ sendGenericRequest(avatar_id, type, method);
+ break;
+ }
}
-void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
- // this is the startup state when send_complete_agent_movement() message is sent.
- // Before this, the AvatarPropertiesRequest message
- // won't work so don't bother trying
- if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
- {
- return;
- }
+ // indicate we're going to make a request
+ addPendingRequest(avatar_id, type);
- if (isPendingRequest(avatar_id, APT_PROPERTIES))
- {
- // waiting for a response, don't re-request
- return;
- }
- // indicate we're going to make a request
- addPendingRequest(avatar_id, APT_PROPERTIES);
+ std::vector<std::string> strings;
+ strings.push_back(avatar_id.asString());
+ send_generic_message(method, strings);
+}
- LLMessageSystem *msg = gMessageSystem;
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
- msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
- gAgent.sendReliableMessage();
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_AvatarID, avatar_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
+ addPendingRequest(avatar_id, APT_PICKS);
+ addPendingRequest(avatar_id, APT_GROUPS);
+ addPendingRequest(avatar_id, APT_NOTES);
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id));
+}
+
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+{
+ sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
}
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
{
- sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
+ sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
}
void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
@@ -174,7 +219,7 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData*
return;
}
- LL_INFOS() << "Sending avatarinfo update" << LL_ENDL;
+ LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL;
// This value is required by sendAvatarPropertiesUpdate method.
//A profile should never be mature. (From the original code)
@@ -266,6 +311,113 @@ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avata
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
}
+// static
+void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ LLAvatarPropertiesProcessor* self = getInstance();
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->removePendingRequest(agent_id, APT_NOTES);
+ return;
+ }
+
+ // Avatar Data
+
+ LLAvatarData avatar_data;
+ std::string birth_date;
+
+ avatar_data.agent_id = agent_id;
+ avatar_data.avatar_id = agent_id;
+ avatar_data.image_id = result["sl_image_id"].asUUID();
+ avatar_data.fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data.partner_id = result["partner_id"].asUUID();
+ avatar_data.about_text = result["sl_about_text"].asString();
+ avatar_data.fl_about_text = result["fl_about_text"].asString();
+ avatar_data.born_on = result["member_since"].asDate();
+ avatar_data.profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data.flags = 0;
+ avatar_data.caption_index = 0;
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES);
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->notifyObservers(agent_id, &avatar_picks, APT_PICKS);
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS);
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_NOTES);
+ self->notifyObservers(agent_id, &avatar_notes, APT_NOTES);
+}
+
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
{
LLAvatarData avatar_data;
@@ -312,6 +464,21 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
That will suppress the warnings and be compatible with old server versions.
WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
*/
+
+ LLInterestsData interests_data;
+
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text );
+ msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text );
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO);
+ self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
}
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
@@ -385,7 +552,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg,
void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
{
LLAvatarPicks avatar_picks;
- msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
@@ -551,6 +718,29 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
gAgent.sendReliableMessage();
}
+void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data)
+{
+ if(!interests_data)
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_AvatarInterestsUpdate);
+ msg->nextBlockFast( _PREHASH_AgentData);
+ msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() );
+ msg->nextBlockFast( _PREHASH_PropertiesData);
+ msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask);
+ msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text);
+ msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask);
+ msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text);
+ msg->addString( _PREHASH_LanguagesText, interests_data->languages_text);
+
+ gAgent.sendReliableMessage();
+}
+
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
{
if (!new_pick) return;
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index b063048c26..f778634d25 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -56,10 +56,22 @@ enum EAvatarProcessorType
APT_PICKS,
APT_PICK_INFO,
APT_TEXTURES,
+ APT_INTERESTS_INFO,
APT_CLASSIFIEDS,
APT_CLASSIFIED_INFO
};
+struct LLInterestsData
+{
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ U32 want_to_mask;
+ std::string want_to_text;
+ U32 skills_mask;
+ std::string skills_text;
+ std::string languages_text;
+};
+
struct LLAvatarData
{
LLUUID agent_id;
@@ -223,6 +235,8 @@ public:
void sendClassifiedDelete(const LLUUID& classified_id);
+ void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
+
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
static std::string accountType(const LLAvatarData* avatar_data);
@@ -234,6 +248,8 @@ public:
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
+ static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id);
+
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
@@ -252,7 +268,10 @@ public:
protected:
- void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method);
+ void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id);
+ void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url);
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index fe94cd27b6..275f17b02a 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -320,9 +320,16 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
// make sure we won't re-report, coro will update timer with correct time later
regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS);
- std::string coroname =
- LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
- boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
+ try
+ {
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
+ }
}
}
@@ -343,10 +350,17 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
// make sure we won't re-request, coro will update timer with correct time later
regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
- // First send a request to get the latest data
- std::string coroname =
- LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
- boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
+ try
+ {
+ // First send a request to get the latest data
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
+ }
}
}
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 8d1e9a438e..1ad2157df0 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -53,6 +53,7 @@
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
#include "llavataractions.h"
+#include "lluiusage.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
@@ -294,6 +295,8 @@ void LLAvatarTracker::copyBuddyList(buddy_map_t& buddies) const
void LLAvatarTracker::terminateBuddy(const LLUUID& id)
{
LL_DEBUGS() << "LLAvatarTracker::terminateBuddy()" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Agent.TerminateFriendship");
+
LLRelationship* buddy = get_ptr_in_map(mBuddyInfo, id);
if(!buddy) return;
mBuddyInfo.erase(id);
@@ -640,6 +643,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
{
(mBuddyInfo[agent_related])->setRightsTo(new_rights);
+ mChangedBuddyIDs.insert(agent_related);
}
}
else
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index e400609a74..72f667a0b8 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -568,8 +568,6 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
// how to chat
gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE);
- LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command
-
// Look for "/20 foo" channel chats.
S32 channel = 0;
LLWString out_text = stripChannelNumber(wtext, &channel);
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index cdf82c77c1..7ff24f64ac 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -48,6 +48,7 @@
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
#include "llfloatersidepanelcontainer.h"
#include "llmutelist.h"
#include "llstylemap.h"
@@ -118,6 +119,7 @@ public:
mSourceType(CHAT_SOURCE_UNKNOWN),
mFrom(),
mSessionID(),
+ mCreationTime(time_corrected()),
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
@@ -403,6 +405,48 @@ public:
{
LLAvatarActions::pay(getAvatarId());
}
+ else if (level == "report_abuse")
+ {
+ std::string time_string;
+ if (mTime > 0) // have frame time
+ {
+ time_t current_time = time_corrected();
+ time_t message_time = current_time - LLFrameTimer::getElapsedSeconds() + mTime;
+
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] ["
+ + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32)message_time;
+ LLStringUtil::format(time_string, substitution);
+ }
+ else
+ {
+ // From history. This might be empty or not full.
+ // See LLChatLogParser::parse
+ time_string = getChild<LLTextBox>("time_box")->getValue().asString();
+
+ // Just add current date if not full.
+ // Should be fine since both times are supposed to be stl
+ if (!time_string.empty() && time_string.size() < 7)
+ {
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] " + time_string;
+
+ LLSD substitution;
+ // To avoid adding today's date to yesterday's timestamp,
+ // use creation time instead of current time
+ substitution["datetime"] = (S32)mCreationTime;
+ LLStringUtil::format(time_string, substitution);
+ }
+ }
+ LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText);
+ }
else if(level == "block_unblock")
{
LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat);
@@ -477,6 +521,10 @@ public:
{
return canModerate(userdata);
}
+ else if (level == "report_abuse")
+ {
+ return gAgentID != mAvatarID;
+ }
else if (level == "can_ban_member")
{
return canBanGroupMember(getAvatarId());
@@ -558,9 +606,15 @@ public:
mTimeBoxTextBox = getChild<LLTextBox>("time_box");
mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance());
- llassert(mInfoCtrl != NULL);
- mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl));
- mInfoCtrl->setVisible(FALSE);
+ if (mInfoCtrl)
+ {
+ mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl));
+ mInfoCtrl->setVisible(FALSE);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create an interface element due to missing or corrupted file inspector_info_ctrl.xml" << LL_ENDL;
+ }
return LLPanel::postBuild();
}
@@ -628,6 +682,12 @@ public:
mSessionID = chat.mSessionID;
mSourceType = chat.mSourceType;
+ // To be able to report a message, we need a copy of it's text
+ // and it's easier to store text directly than trying to get
+ // it from a lltextsegment or chat's mEditor
+ mText = chat.mText;
+ mTime = chat.mTime;
+
//*TODO overly defensive thing, source type should be maintained out there
if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()))
{
@@ -977,6 +1037,9 @@ protected:
EChatSourceType mSourceType;
std::string mFrom;
LLUUID mSessionID;
+ std::string mText;
+ F64 mTime; // IM's frame time
+ time_t mCreationTime; // Views's time
S32 mMinUserNameWidth;
const LLFontGL* mUserNameFont;
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 80d810d159..036ff17074 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -290,9 +290,14 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
pickerp->getCurG (),
pickerp->getCurB (),
subject->mColor.mV[VALPHA] ); // keep current alpha
- subject->mColor = updatedColor;
- subject->setControlValue(updatedColor.getValue());
- pickerp->setRevertOnCancel(TRUE);
+
+ bool color_changed = subject->mColor != updatedColor;
+ if (color_changed)
+ {
+ subject->mColor = updatedColor;
+ subject->setControlValue(updatedColor.getValue());
+ }
+
if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback)
{
subject->mOnCancelCallback( subject, LLSD());
@@ -306,6 +311,13 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
// just commit change
subject->onCommit ();
}
+
+ if (pick_op == COLOR_CANCEL || pick_op == COLOR_SELECT)
+ {
+ // both select and cancel close LLFloaterColorPicker
+ // but COLOR_CHANGE does not
+ subject->setFocus(TRUE);
+ }
}
}
}
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 4a87273372..d4d4f641cf 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -610,6 +610,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -627,7 +628,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
{
LLVector4a local_end = end;
LLVector4a local_intersection;
- if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
@@ -644,7 +645,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it)
{
LLVOVolume *volp = *vol_it;
- if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h
index 8e87299f3e..ea91d70e69 100644
--- a/indra/newview/llcontrolavatar.h
+++ b/indra/newview/llcontrolavatar.h
@@ -68,6 +68,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 86e23e7c83..97b16a5e93 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -391,7 +391,8 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
"can_invite_to_group" == command_name ||
"can_share" == command_name ||
"can_block" == command_name ||
- "can_pay" == command_name)
+ "can_pay" == command_name ||
+ "report_abuse" == command_name)
{
return is_p2p;
}
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a685639427..9ec4fb085b 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -182,6 +182,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
items.push_back(std::string("map"));
items.push_back(std::string("share"));
items.push_back(std::string("pay"));
+ items.push_back(std::string("report_abuse"));
items.push_back(std::string("block_unblock"));
items.push_back(std::string("MuteText"));
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 20fa6d490b..48c7df40df 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -272,9 +272,9 @@ BOOL LLConversationViewSession::postBuild()
default:
break;
}
- }
- refresh();
+ refresh(); // requires vmi
+ }
return TRUE;
}
@@ -490,17 +490,20 @@ void LLConversationViewSession::refresh()
{
// Refresh the session view from its model data
LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
- vmi->resetRefresh();
+ if (vmi)
+ {
+ vmi->resetRefresh();
- if (mSessionTitle)
- {
- if (!highlightFriendTitle(vmi))
- {
- LLStyle::Params title_style;
- title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
- mSessionTitle->setText(vmi->getDisplayName(), title_style);
- }
- }
+ if (mSessionTitle)
+ {
+ if (!highlightFriendTitle(vmi))
+ {
+ LLStyle::Params title_style;
+ title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
+ mSessionTitle->setText(vmi->getDisplayName(), title_style);
+ }
+ }
+ }
// Update all speaking indicators
LLSpeakingIndicatorManager::updateSpeakingIndicators();
@@ -524,8 +527,11 @@ void LLConversationViewSession::refresh()
}
requestArrange();
- // Do the regular upstream refresh
- LLFolderViewFolder::refresh();
+ if (vmi)
+ {
+ // Do the regular upstream refresh
+ LLFolderViewFolder::refresh();
+ }
}
void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id)
@@ -627,8 +633,11 @@ BOOL LLConversationViewParticipant::postBuild()
}
updateChildren();
- LLFolderViewItem::postBuild();
- refresh();
+ if (getViewModelItem())
+ {
+ LLFolderViewItem::postBuild();
+ refresh();
+ }
return TRUE;
}
@@ -712,10 +721,10 @@ void LLConversationViewParticipant::refresh()
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
+
+ // Do the regular upstream refresh
+ LLFolderViewItem::refresh();
}
-
- // Do the regular upstream refresh
- LLFolderViewItem::refresh();
}
void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 7d4961c598..4d9ef99319 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -80,9 +80,14 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
{
}
+void LLDoNotDisturbNotificationStorage::reset()
+{
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+}
+
void LLDoNotDisturbNotificationStorage::initialize()
{
- setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+ reset();
getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index c6f0bf1ab5..237d58b4de 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -61,6 +61,7 @@ public:
void loadNotifications();
void updateNotifications();
void removeNotification(const char * name, const LLUUID& id);
+ void reset();
protected:
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 4a0c9d399f..74625423fe 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -249,12 +249,9 @@ void LLDrawable::cleanupReferences()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
-
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
- gObjectList.removeDrawable(this);
-
gPipeline.unlinkDrawable(this);
removeFromOctree();
@@ -885,7 +882,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
LLFace* facep = getFace(i);
if (facep &&
- (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))
+ (force_update || facep->isInAlphaPool()))
{
LLVector4a box;
box.setSub(facep->mExtents[1], facep->mExtents[0]);
@@ -1255,7 +1252,7 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) :
LLDrawable(root->getVObj(), true),
- LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp)
+ LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW, regionp)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 2372ea01a6..2a0f4c93ac 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -133,6 +133,7 @@ public:
inline LLFace* getFace(const S32 i) const;
inline S32 getNumFaces() const;
face_list_t& getFaces() { return mFaces; }
+ const face_list_t& getFaces() const { return mFaces; }
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index a3837fe10c..7305177e4a 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -37,6 +37,7 @@
#include "lldrawpoolbump.h"
#include "lldrawpoolmaterials.h"
#include "lldrawpoolground.h"
+#include "lldrawpoolpbropaque.h"
#include "lldrawpoolsimple.h"
#include "lldrawpoolsky.h"
#include "lldrawpooltree.h"
@@ -85,9 +86,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_GLOW:
poolp = new LLDrawPoolGlow();
break;
- case POOL_ALPHA:
- poolp = new LLDrawPoolAlpha();
+ case POOL_ALPHA_PRE_WATER:
+ poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_PRE_WATER);
break;
+ case POOL_ALPHA_POST_WATER:
+ poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_POST_WATER);
+ break;
case POOL_AVATAR:
case POOL_CONTROL_AV:
poolp = new LLDrawPoolAvatar(type);
@@ -117,6 +121,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_WL_SKY:
poolp = new LLDrawPoolWLSky();
break;
+ case POOL_PBR_OPAQUE:
+ poolp = new LLDrawPoolPBROpaque();
+ break;
default:
LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;
return NULL;
@@ -207,15 +214,6 @@ void LLDrawPool::renderPostDeferred(S32 pass)
//virtual
void LLDrawPool::endRenderPass( S32 pass )
{
- /*for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- { //dummy cleanup of any currently bound textures
- if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
- {
- gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
- gGL.getTexUnit(i)->disable();
- }
- }*/
-
//make sure channel 0 is active channel
gGL.getTexUnit(0)->activate();
}
@@ -573,7 +571,9 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
params.mGroup->rebuildMesh();
}
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ LLGLDisable cull(params.mGLTFMaterial && params.mGLTFMaterial->mDoubleSided ? GL_CULL_FACE : 0);
+
+ //LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
params.mVertexBuffer->setBufferFast(mask);
params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index fd1b022e5b..620438bb1b 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -48,25 +48,33 @@ public:
enum
{
// Correspond to LLPipeline render type
+ // Also controls render order, so passes that don't use alpha masking/blending should come before
+ // other passes to preserve hierarchical Z for occlusion queries. Occlusion queries happen just
+ // before grass, so grass should be the first alpha masked pool. Other ordering should be done
+ // based on fill rate and likelihood to occlude future passes (faster, large occluders first).
+ //
POOL_SIMPLE = 1,
POOL_GROUND,
POOL_FULLBRIGHT,
POOL_BUMP,
- POOL_MATERIALS,
- POOL_TERRAIN,
- POOL_SKY,
- POOL_WL_SKY,
+ POOL_TERRAIN,
+ POOL_MATERIALS,
+ POOL_GRASS,
POOL_TREE,
POOL_ALPHA_MASK,
POOL_FULLBRIGHT_ALPHA_MASK,
- POOL_GRASS,
+ POOL_SKY,
+ POOL_WL_SKY,
POOL_INVISIBLE, // see below *
POOL_AVATAR,
POOL_CONTROL_AV, // Animesh
- POOL_VOIDWATER,
- POOL_WATER,
POOL_GLOW,
- POOL_ALPHA,
+ POOL_ALPHA_PRE_WATER,
+ POOL_VOIDWATER,
+ POOL_WATER,
+ POOL_ALPHA_POST_WATER,
+ POOL_PBR_OPAQUE,
+ POOL_ALPHA, // note there is no actual "POOL_ALPHA" but pre-water and post-water pools consume POOL_ALPHA faces
NUM_POOL_TYPES,
// * invisiprims work by rendering to the depth buffer but not the color buffer, occluding anything rendered after them
// - and the LLDrawPool types enum controls what order things are rendered in
@@ -129,6 +137,7 @@ class LLRenderPass : public LLDrawPool
public:
// list of possible LLRenderPass types to assign a render batch to
// NOTE: "rigged" variant MUST be non-rigged variant + 1
+ // see LLVolumeGeometryManager::registerFace()
enum
{
PASS_SIMPLE = NUM_POOL_TYPES,
@@ -190,9 +199,147 @@ public:
PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
PASS_ALPHA_INVISIBLE,
PASS_ALPHA_INVISIBLE_RIGGED,
+ PASS_PBR_OPAQUE,
+ PASS_PBR_OPAQUE_RIGGED,
NUM_RENDER_TYPES,
};
+ #ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+ static inline const char* lookupPassName(U32 pass)
+ {
+ switch (pass)
+ {
+ case PASS_SIMPLE:
+ return "PASS_SIMPLE";
+ case PASS_SIMPLE_RIGGED:
+ return "PASS_SIMPLE_RIGGED";
+ case PASS_GRASS:
+ return "PASS_GRASS";
+ case PASS_FULLBRIGHT:
+ return "PASS_FULLBRIGHT";
+ case PASS_FULLBRIGHT_RIGGED:
+ return "PASS_FULLBRIGHT_RIGGED";
+ case PASS_INVISIBLE:
+ return "PASS_INVISIBLE";
+ case PASS_INVISIBLE_RIGGED:
+ return "PASS_INVISIBLE_RIGGED";
+ case PASS_INVISI_SHINY:
+ return "PASS_INVISI_SHINY";
+ case PASS_INVISI_SHINY_RIGGED:
+ return "PASS_INVISI_SHINY_RIGGED";
+ case PASS_FULLBRIGHT_SHINY:
+ return "PASS_FULLBRIGHT_SHINY";
+ case PASS_FULLBRIGHT_SHINY_RIGGED:
+ return "PASS_FULLBRIGHT_SHINY_RIGGED";
+ case PASS_SHINY:
+ return "PASS_SHINY";
+ case PASS_SHINY_RIGGED:
+ return "PASS_SHINY_RIGGED";
+ case PASS_BUMP:
+ return "PASS_BUMP";
+ case PASS_BUMP_RIGGED:
+ return "PASS_BUMP_RIGGED";
+ case PASS_POST_BUMP:
+ return "PASS_POST_BUMP";
+ case PASS_POST_BUMP_RIGGED:
+ return "PASS_POST_BUMP_RIGGED";
+ case PASS_MATERIAL:
+ return "PASS_MATERIAL";
+ case PASS_MATERIAL_RIGGED:
+ return "PASS_MATERIAL_RIGGED";
+ case PASS_MATERIAL_ALPHA:
+ return "PASS_MATERIAL_ALPHA";
+ case PASS_MATERIAL_ALPHA_RIGGED:
+ return "PASS_MATERIAL_ALPHA_RIGGED";
+ case PASS_MATERIAL_ALPHA_MASK:
+ return "PASS_MATERIAL_ALPHA_MASK";
+ case PASS_MATERIAL_ALPHA_MASK_RIGGED:
+ return "PASS_MATERIAL_ALPHA_MASK_RIGGED";
+ case PASS_MATERIAL_ALPHA_EMISSIVE:
+ return "PASS_MATERIAL_ALPHA_EMISSIVE";
+ case PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED:
+ return "PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED";
+ case PASS_SPECMAP:
+ return "PASS_SPECMAP";
+ case PASS_SPECMAP_RIGGED:
+ return "PASS_SPECMAP_RIGGED";
+ case PASS_SPECMAP_BLEND:
+ return "PASS_SPECMAP_BLEND";
+ case PASS_SPECMAP_BLEND_RIGGED:
+ return "PASS_SPECMAP_BLEND_RIGGED";
+ case PASS_SPECMAP_MASK:
+ return "PASS_SPECMAP_MASK";
+ case PASS_SPECMAP_MASK_RIGGED:
+ return "PASS_SPECMAP_MASK_RIGGED";
+ case PASS_SPECMAP_EMISSIVE:
+ return "PASS_SPECMAP_EMISSIVE";
+ case PASS_SPECMAP_EMISSIVE_RIGGED:
+ return "PASS_SPECMAP_EMISSIVE_RIGGED";
+ case PASS_NORMMAP:
+ return "PASS_NORMAMAP";
+ case PASS_NORMMAP_RIGGED:
+ return "PASS_NORMMAP_RIGGED";
+ case PASS_NORMMAP_BLEND:
+ return "PASS_NORMMAP_BLEND";
+ case PASS_NORMMAP_BLEND_RIGGED:
+ return "PASS_NORMMAP_BLEND_RIGGED";
+ case PASS_NORMMAP_MASK:
+ return "PASS_NORMMAP_MASK";
+ case PASS_NORMMAP_MASK_RIGGED:
+ return "PASS_NORMMAP_MASK_RIGGED";
+ case PASS_NORMMAP_EMISSIVE:
+ return "PASS_NORMMAP_EMISSIVE";
+ case PASS_NORMMAP_EMISSIVE_RIGGED:
+ return "PASS_NORMMAP_EMISSIVE_RIGGED";
+ case PASS_NORMSPEC:
+ return "PASS_NORMSPEC";
+ case PASS_NORMSPEC_RIGGED:
+ return "PASS_NORMSPEC_RIGGED";
+ case PASS_NORMSPEC_BLEND:
+ return "PASS_NORMSPEC_BLEND";
+ case PASS_NORMSPEC_BLEND_RIGGED:
+ return "PASS_NORMSPEC_BLEND_RIGGED";
+ case PASS_NORMSPEC_MASK:
+ return "PASS_NORMSPEC_MASK";
+ case PASS_NORMSPEC_MASK_RIGGED:
+ return "PASS_NORMSPEC_MASK_RIGGED";
+ case PASS_NORMSPEC_EMISSIVE:
+ return "PASS_NORMSPEC_EMISSIVE";
+ case PASS_NORMSPEC_EMISSIVE_RIGGED:
+ return "PASS_NORMSPEC_EMISSIVE_RIGGED";
+ case PASS_GLOW:
+ return "PASS_GLOW";
+ case PASS_GLOW_RIGGED:
+ return "PASS_GLOW_RIGGED";
+ case PASS_ALPHA:
+ return "PASS_ALPHA";
+ case PASS_ALPHA_RIGGED:
+ return "PASS_ALPHA_RIGGED";
+ case PASS_ALPHA_MASK:
+ return "PASS_ALPHA_MASK";
+ case PASS_ALPHA_MASK_RIGGED:
+ return "PASS_ALPHA_MASK_RIGGED";
+ case PASS_FULLBRIGHT_ALPHA_MASK:
+ return "PASS_FULLBRIGHT_ALPHA_MASK";
+ case PASS_FULLBRIGHT_ALPHA_MASK_RIGGED:
+ return "PASS_FULLBRIGHT_ALPHA_MASK_RIGGED";
+ case PASS_ALPHA_INVISIBLE:
+ return "PASS_ALPHA_INVISIBLE";
+ case PASS_ALPHA_INVISIBLE_RIGGED:
+ return "PASS_ALPHA_INVISIBLE_RIGGED";
+ case PASS_PBR_OPAQUE:
+ return "PASS_PBR_OPAQUE";
+ case PASS_PBR_OPAQUE_RIGGED:
+ return "PASS_PBR_OPAQUE_RIGGED";
+
+ default:
+ return "Unknown pass";
+ }
+ }
+ #else
+ static inline const char* lookupPass(U32 pass) { return ""; }
+ #endif
+
LLRenderPass(const U32 type);
virtual ~LLRenderPass();
/*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index e674707c01..aa8d4d167e 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -50,14 +50,19 @@
#include "llglcommonfunc.h"
#include "llvoavatar.h"
+#include "llenvironment.h"
+
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
#define current_shader (LLGLSLShader::sCurBoundShaderPtr)
+LLVector4 LLDrawPoolAlpha::sWaterPlane;
+
static BOOL deferred_render = FALSE;
// minimum alpha before discarding a fragment
static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255
+
// minimum alpha before discarding a fragment when rendering impostors
static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f;
@@ -81,6 +86,11 @@ void LLDrawPoolAlpha::prerender()
// TODO: is this even necessay? These are probably set to never discard
LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f);
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f);
+
+ if (LLPipeline::sRenderPBR)
+ {
+ gPipeline.setupHWLights(NULL);
+ }
}
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
@@ -89,11 +99,13 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
}
// set some common parameters on the given shader to prepare for alpha rendering
-static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment)
+static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment, F32 water_sign)
{
static LLCachedControl<F32> displayGamma(gSavedSettings, "RenderDeferredDisplayGamma");
F32 gamma = displayGamma;
+ static LLStaticHashedString waterSign("waterSign");
+
// Does this deferred shader need environment uniforms set such as sun_dir, etc. ?
// NOTE: We don't actually need a gbuffer since we are doing forward rendering (for transparency) post deferred rendering
// TODO: bindDeferredShader() probably should have the updating of the environment uniforms factored out into updateShaderEnvironmentUniforms()
@@ -108,6 +120,8 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
}
shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+ shader->uniform1f(waterSign, water_sign);
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
if (LLPipeline::sImpostorRender)
{
@@ -125,28 +139,54 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
//also prepare rigged variant
if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
{
- prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment);
+ prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment, water_sign);
}
}
+extern BOOL gCubeSnapshot;
+
void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+
+ if ((!LLPipeline::sRenderTransparentWater || gCubeSnapshot) && getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ { // don't render alpha objects on the other side of the water plane if water is opaque
+ return;
+ }
deferred_render = TRUE;
+ F32 water_sign = 1.f;
+
+ if (getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ {
+ water_sign = -1.f;
+ }
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ water_sign *= -1.f;
+ }
+
// prepare shaders
emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
(LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
- prepare_alpha_shader(emissive_shader, true, false);
+ prepare_alpha_shader(emissive_shader, true, false, water_sign);
fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightAlphaMaskProgram;
- prepare_alpha_shader(fullbright_shader, true, false);
+ prepare_alpha_shader(fullbright_shader, true, true, water_sign);
simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
- prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
+ prepare_alpha_shader(simple_shader, false, true, water_sign); //prime simple shader (loads shadow relevant uniforms)
+ LLGLSLShader* materialShader = LLPipeline::sUnderWaterRender ? gDeferredMaterialWaterProgram : gDeferredMaterialProgram;
+ for (int i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ prepare_alpha_shader(&materialShader[i], false, false, water_sign);
+ }
+
+ prepare_alpha_shader(&gDeferredPBRAlphaProgram, false, false, water_sign);
// first pass, render rigged objects only and render to depth buffer
forwardRender(true);
@@ -155,13 +195,13 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
forwardRender();
// final pass, render to depth for depth of field effects
- if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField"))
+ if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField") && !gCubeSnapshot)
{
//update depth buffer sampler
- gPipeline.mScreen.flush();
- gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
- 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
- gPipeline.mDeferredDepth.bindTarget();
+ /*gPipeline.mRT->screen.flush();
+ gPipeline.mRT->deferredDepth.copyContents(gPipeline.mRT->deferredScreen, 0, 0, gPipeline.mRT->deferredScreen.getWidth(), gPipeline.mRT->deferredScreen.getHeight(),
+ 0, 0, gPipeline.mRT->deferredDepth.getWidth(), gPipeline.mRT->deferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ gPipeline.mRT->deferredDepth.bindTarget();*/
simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
simple_shader->bind();
@@ -175,8 +215,8 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2,
true); // <--- discard mostly transparent faces
- gPipeline.mDeferredDepth.flush();
- gPipeline.mScreen.bindTarget();
+ //gPipeline.mRT->deferredDepth.flush();
+ //gPipeline.mRT->screen.bindTarget();
gGL.setColorMask(true, false);
}
@@ -215,9 +255,15 @@ void LLDrawPoolAlpha::render(S32 pass)
{
minimum_alpha = MINIMUM_IMPOSTOR_ALPHA;
}
+
prepare_forward_shader(fullbright_shader, minimum_alpha);
prepare_forward_shader(simple_shader, minimum_alpha);
+ for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
+ {
+ prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha);
+ }
+
//first pass -- rigged only and drawn to depth buffer
forwardRender(true);
@@ -396,62 +442,76 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)
{
bool tex_setup = false;
- if (deferred_render && use_material && current_shader)
+ if (draw->mGLTFMaterial)
{
- if (draw->mNormalMap)
- {
- draw->mNormalMap->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
- }
-
- if (draw->mSpecularMap)
- {
- draw->mSpecularMap->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
- }
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
}
- else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
+ else
{
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
- }
- if (draw->mTextureList.size() > 1)
- {
- for (U32 i = 0; i < draw->mTextureList.size(); ++i)
- {
- if (draw->mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (draw->mTexture.notNull())
- {
- if (use_material)
- {
- current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
- }
- else
- {
- gGL.getTexUnit(0)->bindFast(draw->mTexture);
- }
+ if (deferred_render && use_material && current_shader)
+ {
+ if (draw->mNormalMap)
+ {
+ draw->mNormalMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
+ }
- if (draw->mTextureMatrix)
- {
- tex_setup = true;
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) draw->mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
- }
- else
- {
- gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
- }
- }
+ if (draw->mSpecularMap)
+ {
+ draw->mSpecularMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
+ }
+ }
+ else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
+ {
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+ if (draw->mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < draw->mTextureList.size(); ++i)
+ {
+ if (draw->mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (draw->mTexture.notNull())
+ {
+ if (use_material)
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bindFast(draw->mTexture);
+ }
+
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+ }
+ else
+ {
+ gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
return tex_setup;
}
@@ -600,94 +660,117 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
}
}
- LLRenderPass::applyModelMatrix(params);
+ LLRenderPass::applyModelMatrix(params);
- LLMaterial* mat = NULL;
+ LLMaterial* mat = NULL;
+ LLGLTFMaterial *gltf_mat = params.mGLTFMaterial; // Also see: LLPipeline::getPoolTypeFromTE()
+ bool is_pbr = LLPipeline::sRenderPBR && gltf_mat;
- if (deferred_render)
- {
- mat = params.mMaterial;
- }
-
- if (params.mFullbright)
- {
- // Turn off lighting if it hasn't already been so.
- if (light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- target_shader = fullbright_shader;
+ LLGLDisable cull_face(is_pbr && gltf_mat->mDoubleSided ? GL_CULL_FACE : 0);
- light_enabled = FALSE;
- }
- }
- // Turn on lighting if it isn't already.
- else if (!light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- target_shader = simple_shader;
- light_enabled = TRUE;
- }
+ if (is_pbr && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)
+ {
+ target_shader = &gDeferredPBRAlphaProgram;
+ if (params.mAvatar != nullptr)
+ {
+ target_shader = target_shader->mRiggedVariant;
+ }
- if (deferred_render && mat)
- {
- U32 mask = params.mShaderMask;
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShader(*target_shader);
+ }
- llassert(mask < LLMaterial::SHADER_COUNT);
- target_shader = &(gDeferredMaterialProgram[mask]);
+ params.mGLTFMaterial->bind(target_shader);
+ }
+ else
+ {
+ if (deferred_render)
+ {
+ mat = params.mMaterial;
+ }
+
+ if (params.mFullbright)
+ {
+ // Turn off lighting if it hasn't already been so.
+ if (light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ target_shader = fullbright_shader;
+
+ light_enabled = FALSE;
+ }
+ }
+ // Turn on lighting if it isn't already.
+ else if (!light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ target_shader = simple_shader;
+ light_enabled = TRUE;
+ }
+
+ if (deferred_render && mat)
+ {
+ U32 mask = params.mShaderMask;
+
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = &(gDeferredMaterialProgram[mask]);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ target_shader = &(gDeferredMaterialWaterProgram[mask]);
+ }
+
+ if (params.mAvatar != nullptr)
+ {
+ llassert(target_shader->mRiggedVariant != nullptr);
+ target_shader = target_shader->mRiggedVariant;
+ }
+
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShader(*target_shader);
+ }
+ }
+ else if (!params.mFullbright)
+ {
+ target_shader = simple_shader;
+ }
+ else
+ {
+ target_shader = fullbright_shader;
+ }
- if (LLPipeline::sUnderWaterRender)
- {
- target_shader = &(gDeferredMaterialWaterProgram[mask]);
- }
if (params.mAvatar != nullptr)
{
- llassert(target_shader->mRiggedVariant != nullptr);
target_shader = target_shader->mRiggedVariant;
}
- if (current_shader != target_shader)
- {
- gPipeline.bindDeferredShader(*target_shader);
- }
- }
- else if (!params.mFullbright)
- {
- target_shader = simple_shader;
- }
- else
- {
- target_shader = fullbright_shader;
- }
-
- if (params.mAvatar != nullptr)
- {
- target_shader = target_shader->mRiggedVariant;
- }
-
- if (current_shader != target_shader)
- {// If we need shaders, and we're not ALREADY using the proper shader, then bind it
- // (this way we won't rebind shaders unnecessarily).
- target_shader->bind();
- }
+ if (current_shader != target_shader)
+ {// If we need shaders, and we're not ALREADY using the proper shader, then bind it
+ // (this way we won't rebind shaders unnecessarily).
+ gPipeline.bindDeferredShader(*target_shader);
+ }
- LLVector4 spec_color(1, 1, 1, 1);
- F32 env_intensity = 0.0f;
- F32 brightness = 1.0f;
+ LLVector4 spec_color(1, 1, 1, 1);
+ F32 env_intensity = 0.0f;
+ F32 brightness = 1.0f;
- // We have a material. Supply the appropriate data here.
- if (mat && deferred_render)
- {
- spec_color = params.mSpecColor;
- env_intensity = params.mEnvIntensity;
- brightness = params.mFullbright ? 1.f : 0.f;
- }
+ // We have a material. Supply the appropriate data here.
+ if (mat && deferred_render)
+ {
+ spec_color = params.mSpecColor;
+ env_intensity = params.mEnvIntensity;
+ brightness = params.mFullbright ? 1.f : 0.f;
+ }
- if (current_shader)
- {
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
- current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ if (current_shader)
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ }
}
if (params.mGroup)
@@ -714,7 +797,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
bool tex_setup = TexSetup(&params, (mat != nullptr));
{
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ //LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index fa8ef0f227..2c1ec30958 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -35,9 +35,13 @@ class LLFace;
class LLColor4;
class LLGLSLShader;
-class LLDrawPoolAlpha: public LLRenderPass
+class LLDrawPoolAlpha final: public LLRenderPass
{
public:
+
+ // set by llsettingsvo so lldrawpoolalpha has quick access to the water plane in eye space
+ static LLVector4 sWaterPlane;
+
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
@@ -47,7 +51,7 @@ public:
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
- LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);
+ LLDrawPoolAlpha(U32 type);
/*virtual*/ ~LLDrawPoolAlpha();
/*virtual*/ S32 getNumPostDeferredPasses();
@@ -91,11 +95,4 @@ private:
bool mRigged = false;
};
-class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha
-{
-public:
- LLDrawPoolAlphaPostWater();
- virtual void render(S32 pass = 0);
-};
-
#endif // LL_LLDRAWPOOLALPHA_H
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 4a9a3caaec..67c3000410 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -54,7 +54,7 @@
#include "llviewertexturelist.h"
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
-static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
+static U32 sBufferUsage = GL_STREAM_DRAW;
static U32 sShaderLevel = 0;
LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
@@ -146,11 +146,11 @@ void LLDrawPoolAvatar::prerender()
if (sShaderLevel > 0)
{
- sBufferUsage = GL_DYNAMIC_DRAW_ARB;
+ sBufferUsage = GL_DYNAMIC_DRAW;
}
else
{
- sBufferUsage = GL_STREAM_DRAW_ARB;
+ sBufferUsage = GL_STREAM_DRAW;
}
}
@@ -934,7 +934,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
LLVertexBufferAvatar::LLVertexBufferAvatar()
: LLVertexBuffer(sDataMask,
- GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets
+ GL_STREAM_DRAW) //avatars are always stream draw due to morph targets
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR
}
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 8db6a10e26..75917d0ae3 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -465,6 +465,15 @@ void LLDrawPoolBump::beginFullbrightShiny()
shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
cube_map->setMatrix(1);
+ if (LLPipeline::sReflectionProbesEnabled)
+ {
+ gPipeline.bindReflectionProbes(*shader);
+ }
+ else
+ {
+ gPipeline.setEnvMat(*shader);
+ }
+
// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
// the cube map in the one pass shiny shaders
gGL.getTexUnit(1)->disable();
@@ -526,6 +535,10 @@ void LLDrawPoolBump::endFullbrightShiny()
{
cube_map->disable();
cube_map->restoreMatrix();
+ if (shader->mFeatures.hasReflectionProbes)
+ {
+ gPipeline.unbindReflectionProbes(*shader);
+ }
shader->unbind();
}
@@ -673,6 +686,7 @@ void LLDrawPoolBump::endBump(U32 pass)
S32 LLDrawPoolBump::getNumDeferredPasses()
{
+#if 0 //DEPRECATED -- RenderObjectBump should always be TRUE
if (gSavedSettings.getBOOL("RenderObjectBump"))
{
return 1;
@@ -681,6 +695,9 @@ S32 LLDrawPoolBump::getNumDeferredPasses()
{
return 0;
}
+#else
+ return 1;
+#endif
}
void LLDrawPoolBump::renderDeferred(S32 pass)
@@ -741,6 +758,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
void LLDrawPoolBump::renderPostDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL
for (int i = 0; i < 2; ++i)
{ // two passes -- static and rigged
mRigged = (i == 1);
@@ -1449,11 +1467,11 @@ void LLDrawPoolInvisible::render(S32 pass)
}
U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
- glStencilMask(0);
+ //glStencilMask(0); //deprecated
gGL.setColorMask(false, false);
pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE);
gGL.setColorMask(true, false);
- glStencilMask(0xFFFFFFFF);
+ //glStencilMask(0xFFFFFFFF); //deprecated
if (gPipeline.shadersLoaded())
{
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 2b05f4c453..d97f0714ef 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -260,7 +260,7 @@ void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool
(GLfloat*)&(mpc.mGLMp[0]));
}
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ //LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
params.mVertexBuffer->setBufferFast(mask);
params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp
new file mode 100644
index 0000000000..2f710e570b
--- /dev/null
+++ b/indra/newview/lldrawpoolpbropaque.cpp
@@ -0,0 +1,140 @@
+/**
+ * @file lldrawpoolpbropaque.cpp
+ * @brief LLDrawPoolPBROpaque class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldrawpool.h"
+#include "lldrawpoolpbropaque.h"
+#include "llviewershadermgr.h"
+#include "pipeline.h"
+
+LLDrawPoolPBROpaque::LLDrawPoolPBROpaque() :
+ LLRenderPass(POOL_PBR_OPAQUE)
+{
+}
+
+void LLDrawPoolPBROpaque::prerender()
+{
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+// Forward
+void LLDrawPoolPBROpaque::beginRenderPass(S32 pass)
+{
+}
+
+void LLDrawPoolPBROpaque::endRenderPass( S32 pass )
+{
+}
+
+void LLDrawPoolPBROpaque::render(S32 pass)
+{
+}
+
+void LLDrawPoolPBROpaque::renderDeferred(S32 pass)
+{
+ if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_MATERIALS))
+ {
+ return;
+ }
+
+ const U32 type = LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE;
+ if (!gPipeline.hasRenderType(type))
+ {
+ return;
+ }
+
+ gGL.flush();
+
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable alpha_test(GL_ALPHA_TEST);
+
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ bool rigged = (i == 1);
+ LLGLSLShader* shader = &gDeferredPBROpaqueProgram;
+ U32 vertex_data_mask = getVertexDataMask();
+
+ if (rigged)
+ {
+ shader = shader->mRiggedVariant;
+ vertex_data_mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ shader->bind();
+
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type+i);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type+i);
+
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ {
+ LLDrawInfo* pparams = *i;
+ auto& mat = pparams->mGLTFMaterial;
+
+ mat->bind(shader);
+
+ LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
+
+ bool tex_setup = false;
+ if (pparams->mTextureMatrix)
+ { //special case implementation of texture animation here because of special handling of textures for PBR batches
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)pparams->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+
+ if (rigged)
+ {
+ if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
+ {
+ uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
+ }
+
+ pushBatch(*pparams, vertex_data_mask, FALSE, FALSE);
+ }
+ else
+ {
+ pushBatch(*pparams, vertex_data_mask, FALSE, FALSE);
+ }
+
+ if (tex_setup)
+ {
+ gGL.matrixMode(LLRender::MM_TEXTURE0);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+ }
+ }
+
+ LLGLSLShader::sCurBoundShaderPtr->unbind();
+}
diff --git a/indra/newview/lldrawpoolpbropaque.h b/indra/newview/lldrawpoolpbropaque.h
new file mode 100644
index 0000000000..c355b10b12
--- /dev/null
+++ b/indra/newview/lldrawpoolpbropaque.h
@@ -0,0 +1,63 @@
+/**
+ * @file lldrawpoolpbropaque.h
+ * @brief LLDrawPoolPBrOpaque class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLDRAWPOOLPBROPAQUE_H
+#define LL_LLDRAWPOOLPBROPAQUE_H
+
+#include "lldrawpool.h"
+
+class LLDrawPoolPBROpaque : public LLRenderPass
+{
+public:
+ enum
+ {
+ // See: DEFERRED_VB_MASK
+ VERTEX_DATA_MASK = 0
+ | LLVertexBuffer::MAP_VERTEX
+ | LLVertexBuffer::MAP_NORMAL
+ | LLVertexBuffer::MAP_TEXCOORD0 // Diffuse
+ | LLVertexBuffer::MAP_TEXCOORD1 // Normal
+ | LLVertexBuffer::MAP_TEXCOORD2 // Spec <-- ORM Occlusion Roughness Metal
+ | LLVertexBuffer::MAP_TANGENT
+ | LLVertexBuffer::MAP_COLOR
+ };
+ virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ LLDrawPoolPBROpaque();
+
+ /*virtual*/ S32 getNumDeferredPasses() { return 1; }
+ /*virtual*/ void renderDeferred(S32 pass);
+
+ // Non ALM isn't supported
+ /*virtual*/ void beginRenderPass(S32 pass);
+ /*virtual*/ void endRenderPass(S32 pass);
+ /*virtual*/ S32 getNumPasses() { return 0; }
+ /*virtual*/ void render(S32 pass = 0);
+ /*virtual*/ void prerender();
+
+};
+
+#endif // LL_LLDRAWPOOLPBROPAQUE_H
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 3a1efec91b..55ebf03adc 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -51,7 +51,10 @@ LLDrawPoolSky::LLDrawPoolSky()
void LLDrawPoolSky::prerender()
{
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
- gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
+ if (gSky.mVOSkyp->mDrawable)
+ {
+ gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
+ }
}
void LLDrawPoolSky::render(S32 pass)
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index be33e1b30a..55c8d84838 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -165,19 +165,6 @@ void LLDrawPoolTerrain::render(S32 pass)
LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f);
- if (!gGLManager.mHasMultitexture)
- {
- // No multitexture, render simple land.
- renderSimple(); // Render without multitexture
- return;
- }
- // Render simplified land if video card can't do sufficient multitexturing
- if (!gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2))
- {
- renderSimple(); // Render without multitexture
- return;
- }
-
LLGLSPipeline gls;
if (mShaderLevel > 1 && sShader->mShaderLevel > 0)
@@ -194,10 +181,6 @@ void LLDrawPoolTerrain::render(S32 pass)
{
renderSimple();
}
- else if (gGLManager.mNumTextureUnits < 4)
- {
- renderFull2TU();
- }
else
{
renderFull4TU();
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index a84f62036e..3f39716449 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -57,6 +57,8 @@ BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
+extern BOOL gCubeSnapshot;
+
LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER)
{
}
@@ -104,7 +106,7 @@ void LLDrawPoolWater::restoreGL()
void LLDrawPoolWater::prerender()
{
- mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
+ mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
}
S32 LLDrawPoolWater::getNumPasses()
@@ -117,16 +119,37 @@ S32 LLDrawPoolWater::getNumPasses()
return 0;
}
+S32 LLDrawPoolWater::getNumPostDeferredPasses()
+{
+ return 1;
+}
+
void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
{
- beginRenderPass(pass);
- deferred_render = TRUE;
+ LL_PROFILE_GPU_ZONE("water beginPostDeferredPass")
+ if (LLPipeline::sRenderTransparentWater && !gCubeSnapshot)
+ {
+ // copy framebuffer contents so far to a texture to be used for
+ // reflections and refractions
+ LLRenderTarget& src = gPipeline.mRT->screen;
+ LLRenderTarget& dst = gPipeline.mWaterDis;
+ dst.copyContents(src,
+ 0, 0, src.getWidth(), src.getHeight(),
+ 0, 0, dst.getWidth(), dst.getHeight(),
+ GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+ GL_NEAREST);
+ }
}
-void LLDrawPoolWater::endPostDeferredPass(S32 pass)
+void LLDrawPoolWater::renderPostDeferred(S32 pass)
{
- endRenderPass(pass);
- deferred_render = FALSE;
+ renderWater();
+}
+
+
+S32 LLDrawPoolWater::getNumDeferredPasses()
+{
+ return 0;
}
//===============================
@@ -134,6 +157,7 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass)
//===============================
void LLDrawPoolWater::renderDeferred(S32 pass)
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
if (!LLPipeline::sRenderTransparentWater)
@@ -146,12 +170,14 @@ void LLDrawPoolWater::renderDeferred(S32 pass)
deferred_render = TRUE;
renderWater();
deferred_render = FALSE;
+#endif
}
//=========================================
void LLDrawPoolWater::render(S32 pass)
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
{
@@ -188,12 +214,6 @@ void LLDrawPoolWater::render(S32 pass)
stop_glerror();
- if (!gGLManager.mHasMultitexture)
- {
- // Ack! No multitexture! Bail!
- return;
- }
-
LLFace* refl_face = voskyp->getReflFace();
gPipeline.disableLights();
@@ -243,7 +263,7 @@ void LLDrawPoolWater::render(S32 pass)
glClearStencil(1);
glClear(GL_STENCIL_BUFFER_BIT);
- LLGLEnable gls_stencil(GL_STENCIL_TEST);
+ //LLGLEnable gls_stencil(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
@@ -329,11 +349,13 @@ void LLDrawPoolWater::render(S32 pass)
glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
renderReflection(refl_face);
}
+#endif
}
// for low end hardware
void LLDrawPoolWater::renderOpaqueLegacyWater()
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOSky *voskyp = gSky.mVOSkyp;
@@ -438,11 +460,13 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
}
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+#endif
}
void LLDrawPoolWater::renderReflection(LLFace* face)
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOSky *voskyp = gSky.mVOSkyp;
@@ -468,6 +492,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));
face->renderIndexed();
+#endif
}
void LLDrawPoolWater::renderWater()
@@ -491,6 +516,8 @@ void LLDrawPoolWater::renderWater()
bool moon_up = environment.getIsMoonUp();
bool has_normal_mips = gSavedSettings.getBOOL("RenderWaterMipNormal");
bool underwater = LLViewerCamera::getInstance()->cameraUnderWater();
+ LLColor4 fog_color = LLColor4(pwater->getWaterFogColor(), 0.f);
+ LLColor3 fog_color_linear = linearColor3(fog_color);
if (sun_up)
{
@@ -526,7 +553,7 @@ void LLDrawPoolWater::renderWater()
for( int edge = 0 ; edge < 2; edge++ )
{
// select shader
- if (underwater && LLPipeline::sWaterReflections)
+ if (underwater)
{
shader = deferred_render ? &gDeferredUnderWaterProgram : &gUnderWaterProgram;
}
@@ -541,7 +568,8 @@ void LLDrawPoolWater::renderWater()
shader = deferred_render ? &gDeferredWaterProgram : &gWaterProgram;
}
}
- shader->bind();
+
+ gPipeline.bindDeferredShader(*shader);
// bind textures for water rendering
S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
@@ -582,6 +610,8 @@ void LLDrawPoolWater::renderWater()
// bind reflection texture from RenderTarget
S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ S32 screenDepth = shader->enableTexture(LLShaderMgr::WATER_SCREENDEPTH);
+
F32 screenRes[] = {1.f / gGLViewport[2], 1.f / gGLViewport[3]};
S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
@@ -599,7 +629,6 @@ void LLDrawPoolWater::renderWater()
shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f);
F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
if (screentex > -1)
@@ -608,6 +637,11 @@ void LLDrawPoolWater::renderWater()
gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
}
+ if (screenDepth > -1)
+ {
+ gGL.getTexUnit(screenDepth)->bind(&gPipeline.mWaterDis, true);
+ }
+
if (mShaderLevel == 1)
{
fog_color.mV[VW] = log(fog_density) / log(2);
@@ -621,6 +655,7 @@ void LLDrawPoolWater::renderWater()
shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV);
shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
@@ -645,7 +680,7 @@ void LLDrawPoolWater::renderWater()
shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
if (LLViewerCamera::getInstance()->cameraUnderWater())
@@ -689,7 +724,8 @@ void LLDrawPoolWater::renderWater()
shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
// clean up
- shader->unbind();
+ gPipeline.unbindDeferredShader(*shader);
+
gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
}
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 6f2fc3271d..418430d68a 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -35,7 +35,7 @@ class LLHeavenBody;
class LLWaterSurface;
class LLGLSLShader;
-class LLDrawPoolWater: public LLFacePool
+class LLDrawPoolWater final: public LLFacePool
{
protected:
LLPointer<LLViewerTexture> mWaterImagep[2];
@@ -56,26 +56,26 @@ public:
LLVertexBuffer::MAP_TEXCOORD0
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ virtual U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolWater();
/*virtual*/ ~LLDrawPoolWater();
static void restoreGL();
- /*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); }
- /*virtual*/ void beginPostDeferredPass(S32 pass);
- /*virtual*/ void endPostDeferredPass(S32 pass);
- /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); }
- /*virtual*/ S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void renderDeferred(S32 pass = 0);
-
- /*virtual*/ S32 getNumPasses();
- /*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void prerender();
-
- /*virtual*/ LLViewerTexture *getDebugTexture();
- /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
+
+ S32 getNumPostDeferredPasses() override;
+ void beginPostDeferredPass(S32 pass) override;
+ void renderPostDeferred(S32 pass) override;
+ S32 getNumDeferredPasses() override;
+ void renderDeferred(S32 pass = 0) override;
+
+ S32 getNumPasses() override;
+ void render(S32 pass = 0) override;
+ void prerender() override;
+
+ LLViewerTexture *getDebugTexture() override;
+ LLColor3 getDebugColor() const; // For AGP debug display
void renderReflection(LLFace* face);
void renderWater();
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 9873846669..7157214cbc 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -547,7 +547,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
F32 moon_brightness = (float)psky->getMoonBrightness();
moon_shader->uniform1f(LLShaderMgr::MOON_BRIGHTNESS, moon_brightness);
- moon_shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, gSky.mVOSkyp->getMoon().getColor().mV);
+ moon_shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, gSky.mVOSkyp->getMoon().getColor().mV);
moon_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV);
//moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
moon_shader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, psky->getMoonDirection().mV); // shader: moon_dir
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 63e7887d81..361a7666fa 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,7 +125,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
}
- if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
+ if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -212,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
+ bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
if (use_fbo)
{
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index b76dc6a961..64d89282e2 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -1717,8 +1717,19 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
break;
case LLSD::TypeReal:
- shader->uniform1f(it.second.getShaderKey(), value.asReal());
+ {
+ F32 v = value.asReal();
+ switch (it.second.getShaderKey())
+ { // convert to linear color space if this is a color parameter
+ case LLShaderMgr::HAZE_HORIZON:
+ case LLShaderMgr::HAZE_DENSITY:
+ case LLShaderMgr::CLOUD_SHADOW:
+ //v = sRGBtoLinear(v);
+ break;
+ }
+ shader->uniform1f(it.second.getShaderKey(), v);
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ }
break;
case LLSD::TypeBoolean:
@@ -1729,8 +1740,16 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con
case LLSD::TypeArray:
{
LLVector4 vect4(value);
+
+ switch (it.second.getShaderKey())
+ { // convert to linear color space if this is a color parameter
+ case LLShaderMgr::BLUE_HORIZON:
+ case LLShaderMgr::BLUE_DENSITY:
+ //vect4 = LLVector4(linearColor4(LLColor4(vect4.mV)).mV);
+ break;
+ }
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL;
- shader->uniform4fv(it.second.getShaderKey(), vect4 );
+ shader->uniform3fv(it.second.getShaderKey(), LLVector3(vect4.mV) );
break;
}
@@ -2641,7 +2660,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F3
if (!water.isUndefined())
{
- environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time));
+ environment->injectWaterSettings(water, experience_id, LLSettingsBase::Seconds(transition_time));
}
if (updateenvironment)
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 740396178b..23b56aa579 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -64,7 +64,6 @@
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
-extern BOOL gGLDebugLoggingEnabled;
#define LL_MAX_INDICES_COUNT 1000000
static LLStaticHashedString sTextureIndexIn("texture_index_in");
@@ -587,7 +586,6 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);
}
gGL.syncMatrices();
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x00FF00 );
glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
@@ -668,7 +666,7 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
{
LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);
- LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
+ //LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
if (!wireframe_selection)
{ //modify wireframe into outline selection mode
@@ -1034,12 +1032,12 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po
{
const LLMatrix4& vol_mat = getWorldMatrix();
const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
- const LLVector4a& normal4a = vf.mNormals[0];
- const LLVector4a& tangent = vf.mTangents[0];
- if (!&tangent)
+ if (! (vf.mNormals && vf.mTangents))
{
return;
}
+ const LLVector4a& normal4a = *vf.mNormals;
+ const LLVector4a& tangent = *vf.mTangents;
LLVector4a binormal4a;
binormal4a.setCross3(normal4a, tangent);
@@ -1213,55 +1211,6 @@ bool LLFace::canRenderAsMask()
return false;
}
-
-//static
-void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;
-
- if (vf.mWeights)
- {
- mask |= LLVertexBuffer::MAP_WEIGHT4;
- }
-
- LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW_ARB);
- vf.mVertexBuffer = buff;
-
- buff->allocateBuffer(vf.mNumVertices, 0, true);
-
- LLStrider<LLVector4a> f_vert;
- LLStrider<LLVector4a> f_tangent;
- LLStrider<LLVector3> f_norm;
- LLStrider<LLVector2> f_tc;
-
- buff->getTangentStrider(f_tangent);
- buff->getVertexStrider(f_vert);
- buff->getNormalStrider(f_norm);
- buff->getTexCoord0Strider(f_tc);
-
- for (U32 i = 0; i < vf.mNumVertices; ++i)
- {
- *f_vert++ = vf.mPositions[i];
- *f_tangent++ = vf.mTangents[i];
- *f_tc++ = vf.mTexCoords[i];
- (*f_norm++).set(vf.mNormals[i].getF32ptr());
- }
-
- if (vf.mWeights)
- {
- LLStrider<LLVector4> f_wght;
- buff->getWeight4Strider(f_wght);
- for (U32 i = 0; i < vf.mNumVertices; ++i)
- {
- (*f_wght++).set(vf.mWeights[i].getF32ptr());
- }
- }
-
- buff->flush();
-}
-
//helper function for pushing primitives for transform shaders and cleaning up
//uninitialized data on the tail, plus tracking number of expected primitives
void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
@@ -1306,7 +1255,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
//don't use map range (generates many redundant unmap calls)
- bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
+ bool map_range = false;
if (mVertexBuffer.notNull())
{
@@ -1385,10 +1334,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLColor4U color = tep->getColor();
+ if (tep->getGLTFRenderMaterial())
+ {
+ color = tep->getGLTFRenderMaterial()->mBaseColor;
+ }
+
if (rebuild_color)
{ //decide if shiny goes in alpha channel of color
if (tep &&
- getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
+ !isInAlphaPool()) // <--- alpha channel MUST contain transparency, not shiny
{
LLMaterial* mat = tep->getMaterialParams().get();
@@ -1532,156 +1486,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
-#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
- if (use_transform_feedback &&
- mVertexBuffer->getUsage() == GL_DYNAMIC_COPY_ARB &&
- gTransformPositionProgram.mProgramObject && //transform shaders are loaded
- mVertexBuffer->useVBOs() && //target buffer is in VRAM
- !rebuild_weights && //TODO: add support for weights
- !volume.isUnique()) //source volume is NOT flexi
- { //use transform feedback to pack vertex buffer
- //gGLDebugLoggingEnabled = TRUE;
-
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - transform feedback");
- LLGLEnable discard(GL_RASTERIZER_DISCARD);
- LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
-
- if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
- {
- mVObjp->getVolume()->genTangents(f);
- LLFace::cacheFaceInVRAM(vf);
- buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
- }
-
- LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
-
- gGL.pushMatrix();
- gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix);
-
- if (rebuild_pos)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf position");
- gTransformPositionProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
-
- U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
-
- S32 val = 0;
- U8* vp = (U8*) &val;
- vp[0] = index;
- vp[1] = 0;
- vp[2] = 0;
- vp[3] = 0;
-
- gTransformPositionProgram.uniform1i(sTextureIndexIn, val);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
-
- glEndTransformFeedback();
- }
-
- if (rebuild_color)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf color");
- gTransformColorProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
-
- S32 val = *((S32*) color.mV);
-
- gTransformColorProgram.uniform1i(sColorIn, val);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_emissive)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf emissive");
- gTransformColorProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
-
- U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
-
- S32 glow32 = glow |
- (glow << 8) |
- (glow << 16) |
- (glow << 24);
-
- gTransformColorProgram.uniform1i(sColorIn, glow32);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_normal)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf normal");
- gTransformNormalProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_NORMAL);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_tangent)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tangent");
- gTransformTangentProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TANGENT);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_tcoord)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tcoord");
- gTransformTexCoordProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
-
- bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
-
- if (do_bump)
- {
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
- }
-
- glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
- gGL.popMatrix();
-
- if (cur_shader)
- {
- cur_shader->bind();
- }
- }
- else
-#endif
{
//if it's not fullbright and has no normals, bake sunlight based on face normal
//bool bake_sunlight = !getTextureEntry()->getFullbright() &&
@@ -1795,10 +1599,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
scalea.load3(scale.mV);
LLMaterial* mat = tep->getMaterialParams().get();
+ LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial();
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- if (mat && !do_bump)
+ if ((mat || gltf_mat) && !do_bump)
{
do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
|| mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
@@ -2024,10 +1829,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->flush();
}
- if (!mat && do_bump)
+ if ((!mat && !gltf_mat) && do_bump)
{
mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
+ mVObjp->getVolume()->genTangents(f);
+
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a tangent = vf.mTangents[i];
@@ -2161,20 +1968,19 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
F32* tangents = (F32*) tangent.get();
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(f);
LLVector4Logical mask;
mask.clear();
mask.setElement<3>();
LLVector4a* src = vf.mTangents;
- LLVector4a* end = vf.mTangents+num_vertices;
+ LLVector4a* end = vf.mTangents +num_vertices;
while (src < end)
{
LLVector4a tangent_out;
mat_normal.rotate(*src, tangent_out);
- tangent_out.normalize3fast();
tangent_out.setSelectWithMask(mask, *src, tangent_out);
tangent_out.store4a(tangents);
@@ -2795,3 +2601,10 @@ U64 LLFace::getSkinHash()
{
return mSkinInfo ? mSkinInfo->mHash : 0;
}
+
+bool LLFace::isInAlphaPool() const
+{
+ return getPoolType() == LLDrawPool::POOL_ALPHA ||
+ getPoolType() == LLDrawPool::POOL_ALPHA_PRE_WATER ||
+ getPoolType() == LLDrawPool::POOL_ALPHA_POST_WATER;
+}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index aa00c9d052..a5ea460061 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -81,8 +81,6 @@ public:
PARTICLE = 0x0080,
};
- static void cacheFaceInVRAM(const LLVolumeFace& vf);
-
public:
LLFace(LLDrawable* drawablep, LLViewerObject* objp)
{
@@ -239,6 +237,8 @@ public:
void setDrawOrderIndex(U32 index) { mDrawOrderIndex = index; }
U32 getDrawOrderIndex() const { return mDrawOrderIndex; }
+ // return true if this face is in an alpha draw pool
+ bool isInAlphaPool() const;
public: //aligned members
LLVector4a mExtents[2];
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 1605e4133d..9bb3bac104 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -504,20 +504,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
is.close();
}
- //get time domain
- LLSD::Real cur_total_time = 0.0;
-
- for (U32 i = 0; i < cur_data.size(); ++i)
- {
- cur_total_time += cur_data[i]["Total"]["Time"].asReal();
- }
-
- LLSD::Real base_total_time = 0.0;
- for (U32 i = 0; i < base_data.size(); ++i)
- {
- base_total_time += base_data[i]["Total"]["Time"].asReal();
- }
-
//allocate raw scratch space
LLPointer<LLImageRaw> scratch = new LLImageRaw(1024, 512, 3);
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index c13b63433c..70e8437190 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -471,7 +471,25 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
}
// check if we are dragging an existing item from the favorites bar
- if (item && mDragItemId == item->getUUID())
+ bool existing_drop = false;
+ if (item && mDragItemId == item->getUUID())
+ {
+ // There is a chance of mDragItemId being obsolete
+ // ex: can happen if something interrupts viewer, which
+ // results in viewer not geting a 'mouse up' signal
+ for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i)
+ {
+ LLViewerInventoryItem* currItem = *i;
+
+ if (currItem->getUUID() == mDragItemId)
+ {
+ existing_drop = true;
+ break;
+ }
+ }
+ }
+
+ if (existing_drop)
{
*accept = ACCEPT_YES_SINGLE;
@@ -500,6 +518,7 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
if (mItems.empty())
{
setLandingTab(NULL);
+ mLastTab = NULL;
}
handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
}
@@ -515,6 +534,12 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
{
+ if (mItems.empty())
+ {
+ // Isn't supposed to be empty
+ return;
+ }
+
// Identify the button hovered and the side to drop
LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
bool insert_before = true;
@@ -772,6 +797,14 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
}
LLFavoritesOrderStorage::instance().mPrevFavorites = mItems;
mGetPrevItems = false;
+
+ if (LLFavoritesOrderStorage::instance().isStorageUpdateNeeded())
+ {
+ if (!mItemsChangedTimer.getStarted())
+ {
+ mItemsChangedTimer.start();
+ }
+ }
}
const LLButton::Params& button_params = getButtonParams();
@@ -779,6 +812,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
if(mItems.empty())
{
mBarLabel->setVisible(TRUE);
+ mLastTab = NULL;
}
else
{
@@ -825,6 +859,10 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
dynamic_cast<LLFavoriteLandmarkButton*> (*cur_it);
if (button)
{
+ if (mLastTab == button)
+ {
+ mLastTab = NULL;
+ }
removeChild(button);
delete button;
}
@@ -862,6 +900,17 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
mLastTab = last_new_button;
}
+ if (!mLastTab && mItems.size() > 0)
+ {
+ // mMoreTextBox was removed, so LLFavoriteLandmarkButtons
+ // should be the only ones in the list
+ LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (childs->back());
+ if (button)
+ {
+ mLastTab = button;
+ }
+ }
+
mFirstDropDownItem = j;
// Chevron button
if (mFirstDropDownItem < mItems.size())
@@ -1606,7 +1655,7 @@ void LLFavoritesOrderStorage::destroyClass()
file.close();
LLFile::remove(filename);
}
- if(mSaveOnExit)
+ if(mSaveOnExit || gSavedSettings.getBOOL("UpdateRememberPasswordSetting"))
{
LLFavoritesOrderStorage::instance().saveFavoritesRecord(true);
}
@@ -1650,7 +1699,6 @@ void LLFavoritesOrderStorage::load()
llifstream in_file;
in_file.open(filename.c_str());
LLSD fav_llsd;
- LLSD user_llsd;
if (in_file.is_open())
{
LLSDSerialize::fromXML(fav_llsd, in_file);
@@ -1660,12 +1708,12 @@ void LLFavoritesOrderStorage::load()
in_file.close();
if (fav_llsd.isMap() && fav_llsd.has(gAgentUsername))
{
- user_llsd = fav_llsd[gAgentUsername];
+ mStorageFavorites = fav_llsd[gAgentUsername];
S32 index = 0;
bool needs_validation = gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin");
- for (LLSD::array_iterator iter = user_llsd.beginArray();
- iter != user_llsd.endArray(); ++iter)
+ for (LLSD::array_iterator iter = mStorageFavorites.beginArray();
+ iter != mStorageFavorites.endArray(); ++iter)
{
// Validation
LLUUID fv_id = iter->get("id").asUUID();
@@ -1967,7 +2015,7 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)
}
}
- if((items != mPrevFavorites) || name_changed || pref_changed)
+ if((items != mPrevFavorites) || name_changed || pref_changed || gSavedSettings.getBOOL("UpdateRememberPasswordSetting"))
{
std::string filename = getStoredFavoritesFilename();
if (!filename.empty())
@@ -1988,6 +2036,12 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)
LLSD user_llsd;
S32 fav_iter = 0;
mMissingSLURLs.clear();
+
+ LLSD save_pass;
+ save_pass["save_password"] = gSavedSettings.getBOOL("RememberPassword");
+ user_llsd[fav_iter] = save_pass;
+ fav_iter++;
+
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
{
LLSD value;
@@ -2058,6 +2112,23 @@ void LLFavoritesOrderStorage::showFavoritesOnLoginChanged(BOOL show)
}
}
+bool LLFavoritesOrderStorage::isStorageUpdateNeeded()
+{
+ if (!mRecreateFavoriteStorage)
+ {
+ for (LLSD::array_iterator iter = mStorageFavorites.beginArray();
+ iter != mStorageFavorites.endArray(); ++iter)
+ {
+ if (mFavoriteNames[iter->get("id").asUUID()] != iter->get("name").asString())
+ {
+ mRecreateFavoriteStorage = true;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
{
if (mTargetLandmarkId.isNull()) return;
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2d7ba9df67..3b439b31fd 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -226,8 +226,11 @@ public:
BOOL saveFavoritesRecord(bool pref_changed = false);
void showFavoritesOnLoginChanged(BOOL show);
- LLInventoryModel::item_array_t mPrevFavorites;
+ bool isStorageUpdateNeeded();
+ LLInventoryModel::item_array_t mPrevFavorites;
+ LLSD mStorageFavorites;
+ bool mRecreateFavoriteStorage;
const static S32 NO_INDEX;
static bool mSaveOnExit;
@@ -254,7 +257,6 @@ private:
slurls_map_t mSLURLs;
std::set<LLUUID> mMissingSLURLs;
bool mIsDirty;
- bool mRecreateFavoriteStorage;
struct IsNotInFavorites
{
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index e934041e2e..5817fdbfa0 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -431,41 +431,9 @@ bool LLFeatureManager::loadGPUClass()
LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL;
mGPUClass = GPU_CLASS_3;
#else
- if (gGLManager.mGLVersion <= 2.f)
- {
- mGPUClass = GPU_CLASS_0;
- }
- else if (gGLManager.mGLVersion <= 3.f)
- {
- mGPUClass = GPU_CLASS_1;
- }
- else if (gGLManager.mGLVersion < 3.3f)
- {
- mGPUClass = GPU_CLASS_2;
- }
- else if (gGLManager.mGLVersion < 4.f)
- {
- mGPUClass = GPU_CLASS_3;
- }
- else
- {
- mGPUClass = GPU_CLASS_4;
- }
- if (gGLManager.mIsIntel && mGPUClass > GPU_CLASS_1)
- {
- // Intels are generally weaker then other GPUs despite having advanced features
- mGPUClass = (EGPUClass)(mGPUClass - 1);
- }
+ mGPUClass = GPU_CLASS_2;
#endif
}
- else if (gGLManager.mGLVersion <= 2.f)
- {
- mGPUClass = GPU_CLASS_0;
- }
- else if (gGLManager.mGLVersion <= 3.f)
- {
- mGPUClass = GPU_CLASS_1;
- }
else if (gbps <= 5.f)
{
mGPUClass = GPU_CLASS_0;
@@ -607,7 +575,7 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
{
LLViewerShaderMgr::sSkipReload = true;
-
+ flush_glerror(); // Whatever may have already happened (e.g., to cause us to change), don't let confuse it with new initializations.
applyBaseMasks();
// if we're passed an invalid level, default to "Low"
@@ -679,22 +647,14 @@ void LLFeatureManager::applyBaseMasks()
{
maskFeatures("TexUnit8orLess");
}
- if (gGLManager.mHasMapBufferRange)
- {
- maskFeatures("MapBufferRange");
- }
if (gGLManager.mVRAM > 512)
{
maskFeatures("VRAMGT512");
}
-
-#if LL_DARWIN
- const LLOSInfo& osInfo = LLOSInfo::instance();
- if (osInfo.mMajorVer == 10 && osInfo.mMinorVer < 7)
- {
- maskFeatures("OSX_10_6_8");
- }
-#endif
+ if (gGLManager.mGLVersion < 3.99f)
+ {
+ maskFeatures("GL3");
+ }
// now mask by gpu string
// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
new file mode 100644
index 0000000000..2d3015635c
--- /dev/null
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -0,0 +1,103 @@
+/**
+ * @file llfetchedgltfmaterial.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfetchedgltfmaterial.h"
+
+#include "llviewertexturelist.h"
+#include "llavatarappearancedefines.h"
+#include "llshadermgr.h"
+
+LLFetchedGLTFMaterial::LLFetchedGLTFMaterial()
+ : LLGLTFMaterial()
+ , mExpectedFlusTime(0.f)
+ , mActive(true)
+ , mFetching(false)
+{
+
+}
+
+LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial()
+{
+
+}
+
+void LLFetchedGLTFMaterial::bind(LLGLSLShader* shader)
+{
+ // glTF 2.0 Specification 3.9.4. Alpha Coverage
+ // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK
+ F32 min_alpha = -1.0;
+
+ if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ min_alpha = mAlphaCutoff;
+ }
+ shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha);
+
+ if (mBaseColorTexture.notNull())
+ {
+ gGL.getTexUnit(0)->bindFast(mBaseColorTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+
+ if (mNormalTexture.notNull())
+ {
+ shader->bindTexture(LLShaderMgr::BUMP_MAP, mNormalTexture);
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ }
+
+ if (mMetallicRoughnessTexture.notNull())
+ {
+ shader->bindTexture(LLShaderMgr::SPECULAR_MAP, mMetallicRoughnessTexture); // PBR linear packed Occlusion, Roughness, Metal.
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+ if (mEmissiveTexture.notNull())
+ {
+ shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, mEmissiveTexture); // PBR sRGB Emissive
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+ // NOTE: base color factor is baked into vertex stream
+
+ shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor);
+ shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor);
+ shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV);
+
+}
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
new file mode 100644
index 0000000000..3b2801bf77
--- /dev/null
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -0,0 +1,57 @@
+/**
+ * @file llfetchedgltfmaterial.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+
+#pragma once
+
+#include "llgltfmaterial.h"
+#include "llpointer.h"
+#include "llviewertexture.h"
+
+class LLGLSLShader;
+
+class LLFetchedGLTFMaterial: public LLGLTFMaterial
+{
+ friend class LLGLTFMaterialList; // for lifetime management
+public:
+ LLFetchedGLTFMaterial();
+ virtual ~LLFetchedGLTFMaterial();
+
+ // bind this material for rendering
+ void bind(LLGLSLShader* shader);
+
+ // Textures used for fetching/rendering
+ LLPointer<LLViewerFetchedTexture> mBaseColorTexture;
+ LLPointer<LLViewerFetchedTexture> mNormalTexture;
+ LLPointer<LLViewerFetchedTexture> mMetallicRoughnessTexture;
+ LLPointer<LLViewerFetchedTexture> mEmissiveTexture;
+
+protected:
+ //Lifetime management
+ F64 mExpectedFlusTime; // since epoch in seconds
+ bool mActive;
+ bool mFetching;
+};
+
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 3669fb1eeb..1dd9a43b72 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -55,13 +55,13 @@ LLFilePicker LLFilePicker::sInstance;
#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define ANIM_FILTER L"Animations (*.bvh; *.anim)\0*.bvh;*.anim\0"
#define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0"
-#ifdef _CORY_TESTING
-#define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0"
-#endif
+#define GLTF_FILTER L"glTF (*.gltf; *.glb)\0*.gltf;*.glb\0"
#define XML_FILTER L"XML files (*.xml)\0*.xml\0"
#define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
+#define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0"
+#define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"
#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
#endif
@@ -193,16 +193,14 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = ANIM_FILTER \
L"\0";
break;
- case FFLOAD_COLLADA:
+ case FFLOAD_GLTF:
+ mOFN.lpstrFilter = GLTF_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_COLLADA:
mOFN.lpstrFilter = COLLADA_FILTER \
L"\0";
break;
-#ifdef _CORY_TESTING
- case FFLOAD_GEOMETRY:
- mOFN.lpstrFilter = GEOMETRY_FILTER \
- L"\0";
- break;
-#endif
case FFLOAD_XML:
mOFN.lpstrFilter = XML_FILTER \
L"\0";
@@ -219,6 +217,16 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = MODEL_FILTER \
L"\0";
break;
+ case FFLOAD_MATERIAL:
+ mOFN.lpstrFilter = MATERIAL_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_MATERIAL_TEXTURE:
+ mOFN.lpstrFilter = MATERIAL_TEXTURES_FILTER \
+ MATERIAL_FILTER \
+ IMAGE_FILTER \
+ L"\0";
+ break;
case FFLOAD_SCRIPT:
mOFN.lpstrFilter = SCRIPT_FILTER \
L"\0";
@@ -480,18 +488,16 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
L"XAF Anim File (*.xaf)\0*.xaf\0" \
L"\0";
break;
-#ifdef _CORY_TESTING
- case FFSAVE_GEOMETRY:
+ case FFSAVE_GLTF:
if (filename.empty())
{
- wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ wcsncpy( mFilesW,L"untitled.glb", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
}
- mOFN.lpstrDefExt = L"slg";
+ mOFN.lpstrDefExt = L"glb";
mOFN.lpstrFilter =
- L"SLG SL Geometry File (*.slg)\0*.slg\0" \
+ L"glTF Asset File (*.gltf *.glb)\0*.gltf;*.glb\0" \
L"\0";
break;
-#endif
case FFSAVE_XML:
if (filename.empty())
{
@@ -621,14 +627,13 @@ std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //
allowedv->push_back("bvh");
allowedv->push_back("anim");
break;
+ case FFLOAD_GLTF:
+ allowedv->push_back("gltf");
+ allowedv->push_back("glb");
+ break;
case FFLOAD_COLLADA:
allowedv->push_back("dae");
break;
-#ifdef _CORY_TESTING
- case FFLOAD_GEOMETRY:
- allowedv->push_back("slg");
- break;
-#endif
case FFLOAD_XML:
allowedv->push_back("xml");
break;
@@ -728,13 +733,11 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena
extension = "xaf";
break;
-#ifdef _CORY_TESTING
- case FFSAVE_GEOMETRY:
+ case FFSAVE_GLTF:
type = "\?\?\?\?";
creator = "\?\?\?\?";
- extension = "slg";
+ extension = "glb";
break;
-#endif
case FFSAVE_XML:
type = "\?\?\?\?";
@@ -1354,10 +1357,13 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
case FFLOAD_XML:
filtername = add_xml_filter_to_gtkchooser(picker);
break;
- case FFLOAD_COLLADA:
- filtername = add_collada_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_IMAGE:
+ case FFLOAD_GLTF:
+ filtername = dead_code_should_blow_up_here(picker);
+ break;
+ case FFLOAD_COLLADA:
+ filtername = add_collada_filter_to_gtkchooser(picker);
+ break;
+ case FFLOAD_IMAGE:
filtername = add_imageload_filter_to_gtkchooser(picker);
break;
case FFLOAD_SCRIPT:
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 04ba4416d7..a03f3f6711 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -77,9 +77,7 @@ public:
FFLOAD_WAV = 2,
FFLOAD_IMAGE = 3,
FFLOAD_ANIM = 4,
-#ifdef _CORY_TESTING
- FFLOAD_GEOMETRY = 5,
-#endif
+ FFLOAD_GLTF = 5,
FFLOAD_XML = 6,
FFLOAD_SLOBJECT = 7,
FFLOAD_RAW = 8,
@@ -88,7 +86,9 @@ public:
FFLOAD_SCRIPT = 11,
FFLOAD_DICTIONARY = 12,
FFLOAD_DIRECTORY = 13, // To call from lldirpicker.
- FFLOAD_EXE = 14 // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
+ FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
+ FFLOAD_MATERIAL = 15,
+ FFLOAD_MATERIAL_TEXTURE = 16,
};
enum ESaveFilter
@@ -99,9 +99,7 @@ public:
FFSAVE_BMP = 5,
FFSAVE_AVI = 6,
FFSAVE_ANIM = 7,
-#ifdef _CORY_TESTING
- FFSAVE_GEOMETRY = 8,
-#endif
+ FFSAVE_GLTF = 8,
FFSAVE_XML = 9,
FFSAVE_COLLADA = 10,
FFSAVE_RAW = 11,
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 4f3c2d8d34..d5115df35f 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -386,7 +386,8 @@ void LLVolumeImplFlexible::doIdleUpdate()
U64 throttling_delay = (virtual_frame_num + id) % update_period;
if ((throttling_delay == 0 && mLastFrameNum < virtual_frame_num) //one or more virtual frames per frame
- || (mLastFrameNum + update_period < virtual_frame_num)) // missed virtual frame
+ || (mLastFrameNum + update_period < virtual_frame_num) // missed virtual frame
+ || mLastFrameNum > virtual_frame_num) // overflow
{
// We need mLastFrameNum to compensate for 'unreliable time' and to filter 'duplicate' frames
// If happened too late, subtract throttling_delay (it is zero otherwise)
@@ -787,10 +788,7 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
volume->updateRelativeXform();
- if (mRenderRes > -1)
- {
- doFlexibleUpdate();
- }
+ doFlexibleUpdate();
// Object may have been rotated, which means it needs a rebuild. See SL-47220
BOOL rotated = FALSE;
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index ffbb0bbee9..c075f7e8bd 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -114,6 +114,11 @@ BOOL LLFloater360Capture::postBuild()
// by default each time vs restoring the last value
mQualityRadioGroup->setSelectedIndex(0);
+ return true;
+}
+
+void LLFloater360Capture::onOpen(const LLSD& key)
+{
// Construct a URL pointing to the first page to load. Although
// we do not use this page for anything (after some significant
// design changes), we retain the code to load the start page
@@ -154,8 +159,6 @@ BOOL LLFloater360Capture::postBuild()
// We do an initial capture when the floater is opened, albeit at a 'preview'
// quality level (really low resolution, but really fast)
onCapture360ImagesBtn();
-
- return true;
}
// called when the user choose a quality level using
diff --git a/indra/newview/llfloater360capture.h b/indra/newview/llfloater360capture.h
index 6da7ee074a..8f765c0b1b 100644
--- a/indra/newview/llfloater360capture.h
+++ b/indra/newview/llfloater360capture.h
@@ -47,6 +47,7 @@ class LLFloater360Capture:
~LLFloater360Capture();
BOOL postBuild() override;
+ void onOpen(const LLSD& key) override;
void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
void changeInterestListMode(bool send_everything);
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
index ec05ba924c..0964daa4d5 100644
--- a/indra/newview/llfloaterautoreplacesettings.cpp
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -350,7 +350,7 @@ void LLFloaterAutoReplaceSettings::onDeleteEntry()
// called when the Import List button is pressed
void LLFloaterAutoReplaceSettings::onImportList()
{
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterAutoReplaceSettings::loadListFromFile(const std::vector<std::string>& filenames)
@@ -537,7 +537,7 @@ void LLFloaterAutoReplaceSettings::onExportList()
{
std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString();
std::string listFileName = listName + ".xml";
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName);
}
void LLFloaterAutoReplaceSettings::saveListToFile(const std::vector<std::string>& filenames, std::string listName)
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index ab95bc06b8..0186c4aebe 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -105,6 +105,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
mNumResultsReturned(0),
mNearMeListComplete(FALSE),
mCloseOnSelect(FALSE),
+ mExcludeAgentFromSearchResults(FALSE),
mContextConeOpacity (0.f),
mContextConeInAlpha(0.f),
mContextConeOutAlpha(0.f),
@@ -295,7 +296,7 @@ void LLFloaterAvatarPicker::populateNearMe()
for(U32 i=0; i<avatar_ids.size(); i++)
{
LLUUID& av = avatar_ids[i];
- if(av == gAgent.getID()) continue;
+ if(mExcludeAgentFromSearchResults && (av == gAgent.getID())) continue;
LLSD element;
element["id"] = av; // value
LLAvatarName av_name;
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index a1a06706bc..a3cc939f85 100644
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -306,6 +306,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve
( asstype == LLAssetType::AT_LSL_TEXT && gSavedSettings.getBOOL("BulkChangeIncludeScripts" )) ||
( asstype == LLAssetType::AT_SOUND && gSavedSettings.getBOOL("BulkChangeIncludeSounds" )) ||
( asstype == LLAssetType::AT_SETTINGS && gSavedSettings.getBOOL("BulkChangeIncludeSettings" )) ||
+ ( asstype == LLAssetType::AT_MATERIAL && gSavedSettings.getBOOL("BulkChangeIncludeMaterials")) ||
( asstype == LLAssetType::AT_TEXTURE && gSavedSettings.getBOOL("BulkChangeIncludeTextures" )))
{
LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index a3037ed651..ed3dc37043 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -294,7 +294,7 @@ BOOL LLFloaterBvhPreview::postBuild()
loaderp->serialize(dp);
dp.reset();
LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL;
- BOOL success = motionp && motionp->deserialize(dp, mMotionID);
+ BOOL success = motionp && motionp->deserialize(dp, mMotionID, false);
LL_INFOS("BVH") << "Done" << LL_ENDL;
delete []buffer;
@@ -1047,7 +1047,12 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT
mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
mDummyAvatar->mSpecialRenderMode = 1;
mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
- mDummyAvatar->hideSkirt();
+
+ // on idle overall apperance update will set skirt to visible, so either
+ // call early or account for mSpecialRenderMode in updateMeshVisibility
+ mDummyAvatar->updateOverallAppearance();
+ mDummyAvatar->hideHair();
+ mDummyAvatar->hideSkirt();
// stop extraneous animations
mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE );
@@ -1135,6 +1140,7 @@ BOOL LLPreviewAnimation::render()
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
avatarp->dirtyMesh();
+ gPipeline.enableLightsPreview();
avatarPoolp->renderAvatars(avatarp); // renders only one avatar
}
}
diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
index 45aea00a49..67c412dfa6 100644
--- a/indra/newview/llfloaterchatvoicevolume.cpp
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -35,7 +35,7 @@ LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
{
LLInspect::onOpen(key);
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(key);
}
LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
diff --git a/indra/newview/llfloaterclassified.cpp b/indra/newview/llfloaterclassified.cpp
new file mode 100644
index 0000000000..3520b0f67a
--- /dev/null
+++ b/indra/newview/llfloaterclassified.cpp
@@ -0,0 +1,71 @@
+/**
+ * @file llfloaterclassified.cpp
+ * @brief LLFloaterClassified for displaying classifieds.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterclassified.h"
+
+LLFloaterClassified::LLFloaterClassified(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLFloaterClassified::~LLFloaterClassified()
+{
+}
+
+void LLFloaterClassified::onOpen(const LLSD& key)
+{
+ LLPanel* panel = findChild<LLPanel>("main_panel", true);
+ if (panel)
+ {
+ panel->onOpen(key);
+ }
+ if (key.has("classified_name"))
+ {
+ setTitle(key["classified_name"].asString());
+ }
+ LLFloater::onOpen(key);
+}
+
+BOOL LLFloaterClassified::postBuild()
+{
+ return TRUE;
+}
+
+
+bool LLFloaterClassified::matchesKey(const LLSD& key)
+{
+ bool is_mkey_valid = mKey.has("classified_id");
+ bool is_key_valid = key.has("classified_id");
+ if (is_mkey_valid && is_key_valid)
+ {
+ return key["classified_id"].asUUID() == mKey["classified_id"].asUUID();
+ }
+ return is_mkey_valid == is_key_valid;
+}
+
+// eof
diff --git a/indra/newview/llpanelme.h b/indra/newview/llfloaterclassified.h
index 60e9d4317d..2c95d82b2c 100644
--- a/indra/newview/llpanelme.h
+++ b/indra/newview/llfloaterclassified.h
@@ -1,50 +1,45 @@
-/**
- * @file llpanelme.h
- * @brief Side tray "Me" (My Profile) panel
+/**
+ * @file llfloaterclassified.h
+ * @brief LLFloaterClassified for displaying classifieds.
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#ifndef LL_LLPANELMEPROFILE_H
-#define LL_LLPANELMEPROFILE_H
+#ifndef LL_LLFLOATERCLASSIFIED_H
+#define LL_LLFLOATERCLASSIFIED_H
-#include "llpanel.h"
-#include "llpanelprofile.h"
+#include "llfloater.h"
-/**
-* Panel for displaying Agent's Picks and Classifieds panel.
-* LLPanelMe allows user to edit his picks and classifieds.
-*/
-class LLPanelMe : public LLPanelProfile
+class LLFloaterClassified : public LLFloater
{
- LOG_CLASS(LLPanelMe);
-
+ LOG_CLASS(LLFloaterClassified);
public:
+ LLFloaterClassified(const LLSD& key);
+ virtual ~LLFloaterClassified();
- LLPanelMe();
-
- /*virtual*/ void onOpen(const LLSD& key);
+ void onOpen(const LLSD& key) override;
+ BOOL postBuild() override;
- /*virtual*/ BOOL postBuild();
+ bool matchesKey(const LLSD& key) override;
};
-#endif // LL_LLPANELMEPROFILE_H
+#endif // LL_LLFLOATERCLASSIFIED_H
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 1a784223c2..ba91277c79 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -173,7 +173,6 @@ void LLFloaterColorPicker::showUI ()
openFloater(getKey());
setVisible ( TRUE );
setFocus ( TRUE );
- setRevertOnCancel(FALSE);
// HACK: if system color picker is required - close the SL one we made and use default system dialog
if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) )
@@ -185,15 +184,23 @@ void LLFloaterColorPicker::showUI ()
// code that will get switched in for default system color picker
if ( swatch )
{
+ // Todo: this needs to be threaded for viewer not to timeout
LLColor4 curCol = swatch->get ();
send_agent_pause();
- getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
+ bool commit = getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
send_agent_resume();
- setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
- setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
-
- LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE );
+ if (commit)
+ {
+ setOrigRgb(curCol[0], curCol[1], curCol[2]);
+ setCurRgb(curCol[0], curCol[1], curCol[2]);
+
+ LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_SELECT);
+ }
+ else
+ {
+ LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_CANCEL);
+ }
}
closeFloater();
@@ -391,10 +398,7 @@ void LLFloaterColorPicker::onClickCancel ( void* data )
if ( self )
{
- if(self->getRevertOnCancel())
- {
- self->cancelSelection ();
- }
+ self->cancelSelection();
self->closeFloater();
}
}
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 16974a872e..39dbc5b763 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -104,9 +104,6 @@ class LLFloaterColorPicker
void setMouseDownInSwatch (BOOL mouse_down_in_swatch);
BOOL getMouseDownInSwatch () { return mMouseDownInSwatch; }
- void setRevertOnCancel (BOOL revertOnCancel) { mRevertOnCancel = revertOnCancel; };
- BOOL getRevertOnCancel () { return mRevertOnCancel; }
-
BOOL isColorChanged ();
// called when text entries (RGB/HSL etc.) are changed by user
@@ -149,8 +146,6 @@ class LLFloaterColorPicker
BOOL mMouseDownInHueRegion;
BOOL mMouseDownInSwatch;
- BOOL mRevertOnCancel;
-
const S32 mRGBViewerImageLeft;
const S32 mRGBViewerImageTop;
const S32 mRGBViewerImageWidth;
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
index 6b1d9306fb..7def855d83 100644
--- a/indra/newview/llfloatercreatelandmark.cpp
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -46,19 +46,60 @@
typedef std::pair<LLUUID, std::string> folder_pair_t;
-class LLLandmarksInventoryObserver : public LLInventoryAddedObserver
+class LLLandmarksInventoryObserver : public LLInventoryObserver
{
public:
LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :
mFloater(create_landmark_floater)
{}
+ void changed(U32 mask) override
+ {
+ if (mFloater->getItem())
+ {
+ checkChanged(mask);
+ }
+ else
+ {
+ checkCreated(mask);
+ }
+ }
+
protected:
- /*virtual*/ void done()
+ void checkCreated(U32 mask)
{
+ if (gInventory.getAddedIDs().empty())
+ {
+ return;
+ }
+
+ if (!(mask & LLInventoryObserver::ADD) ||
+ !(mask & LLInventoryObserver::CREATE) ||
+ !(mask & LLInventoryObserver::UPDATE_CREATE))
+ {
+ return;
+ }
+
mFloater->setItem(gInventory.getAddedIDs());
}
+ void checkChanged(U32 mask)
+ {
+ if (gInventory.getChangedIDs().empty())
+ {
+ return;
+ }
+
+ if ((mask & LLInventoryObserver::LABEL) ||
+ (mask & LLInventoryObserver::INTERNAL) ||
+ (mask & LLInventoryObserver::REMOVE) ||
+ (mask & LLInventoryObserver::STRUCTURE) ||
+ (mask & LLInventoryObserver::REBUILD))
+ {
+ mFloater->updateItem(gInventory.getChangedIDs(), mask);
+ }
+ }
+
private:
LLFloaterCreateLandmark* mFloater;
};
@@ -85,6 +126,9 @@ BOOL LLFloaterCreateLandmark::postBuild()
getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this));
+ mLandmarkTitleEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); });
+ mNotesEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); });
+
mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
return TRUE;
@@ -204,6 +248,33 @@ void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)
}
}
+void LLFloaterCreateLandmark::onCommitTextChanges()
+{
+ if (mItem.isNull())
+ {
+ return;
+ }
+ std::string current_title_value = mLandmarkTitleEditor->getText();
+ std::string item_title_value = mItem->getName();
+ std::string current_notes_value = mNotesEditor->getText();
+ std::string item_notes_value = mItem->getDescription();
+
+ LLStringUtil::trim(current_title_value);
+ LLStringUtil::trim(current_notes_value);
+
+ if (!current_title_value.empty() &&
+ (item_title_value != current_title_value || item_notes_value != current_notes_value))
+ {
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
+ new_item->rename(current_title_value);
+ new_item->setDescription(current_notes_value);
+ LLPointer<LLInventoryCallback> cb;
+ LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0);
+ gInventory.accountForUpdate(up);
+ update_inventory_item(new_item, cb);
+ }
+}
+
void LLFloaterCreateLandmark::onCreateFolderClicked()
{
LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(),
@@ -278,6 +349,8 @@ void LLFloaterCreateLandmark::onSaveClicked()
new_item->updateParentOnServer(FALSE);
}
+ removeObserver();
+
gInventory.updateItem(new_item);
gInventory.notifyObservers();
@@ -286,6 +359,7 @@ void LLFloaterCreateLandmark::onSaveClicked()
void LLFloaterCreateLandmark::onCancelClicked()
{
+ removeObserver();
if (!mItem.isNull())
{
LLUUID item_id = mItem->getUUID();
@@ -314,10 +388,59 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
{
if(!getItem())
{
- removeObserver();
mItem = item;
+ mAssetID = mItem->getAssetUUID();
+ setVisibleAndFrontmost(true);
break;
}
}
}
}
+
+void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask)
+{
+ if (!getItem())
+ {
+ return;
+ }
+
+ LLUUID landmark_id = getItem()->getUUID();
+
+ for (uuid_set_t::const_iterator item_iter = items.begin();
+ item_iter != items.end();
+ ++item_iter)
+ {
+ const LLUUID& item_id = (*item_iter);
+ if (landmark_id == item_id)
+ {
+ if (getItem() != gInventory.getItem(item_id))
+ {
+ // item is obsolete or removed
+ closeFloater();
+ }
+
+ LLUUID folder_id = mFolderCombo->getValue().asUUID();
+ if (folder_id != mItem->getParentUUID())
+ {
+ // user moved landmark in inventory,
+ // assume that we are done all other changes should already be commited
+ closeFloater();
+ }
+
+ if ((mask & LLInventoryObserver::INTERNAL) && mAssetID != mItem->getAssetUUID())
+ {
+ closeFloater();
+ }
+
+ if (mask & LLInventoryObserver::LABEL)
+ {
+ mLandmarkTitleEditor->setText(mItem->getName());
+ }
+
+ if (mask & LLInventoryObserver::INTERNAL)
+ {
+ mNotesEditor->setText(mItem->getDescription());
+ }
+ }
+ }
+}
diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h
index 74ac5e651c..d84f5ae1fc 100644
--- a/indra/newview/llfloatercreatelandmark.h
+++ b/indra/newview/llfloatercreatelandmark.h
@@ -49,6 +49,7 @@ public:
void onOpen(const LLSD& key);
void setItem(const uuid_set_t& items);
+ void updateItem(const uuid_set_t& items, U32 mask);
LLInventoryItem* getItem() { return mItem; }
@@ -56,6 +57,7 @@ private:
void setLandmarkInfo(const LLUUID &folder_id);
void removeObserver();
void populateFoldersList(const LLUUID &folder_id = LLUUID::null);
+ void onCommitTextChanges();
void onCreateFolderClicked();
void onSaveClicked();
void onCancelClicked();
@@ -66,6 +68,7 @@ private:
LLLineEditor* mLandmarkTitleEditor;
LLTextEditor* mNotesEditor;
LLUUID mLandmarksID;
+ LLUUID mAssetID;
LLLandmarksInventoryObserver* mInventoryObserver;
LLPointer<LLInventoryItem> mItem;
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
new file mode 100644
index 0000000000..3b0c67415a
--- /dev/null
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file llfloaterdisplayname.cpp
+ * @author Leyla Farazha
+ * @brief Implementation of the LLFloaterDisplayName class.
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
+#include "llfloater.h"
+
+#include "llnotificationsutil.h"
+#include "llviewerdisplayname.h"
+
+#include "llnotifications.h"
+#include "llfloaterdisplayname.h"
+#include "llavatarnamecache.h"
+
+#include "llagent.h"
+
+
+class LLFloaterDisplayName : public LLFloater
+{
+public:
+ LLFloaterDisplayName(const LLSD& key);
+ virtual ~LLFloaterDisplayName() { }
+ /*virtual*/ BOOL postBuild();
+ void onSave();
+ void onCancel();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+private:
+
+ void onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content);
+};
+
+LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
+ LLFloater(key)
+{
+}
+
+void LLFloaterDisplayName::onOpen(const LLSD& key)
+{
+ getChild<LLUICtrl>("display_name_editor")->clear();
+ getChild<LLUICtrl>("display_name_confirm")->clear();
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(gAgent.getID(), &av_name);
+
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
+
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // ...can't update until some time in the future
+ F64 next_update_local_secs =
+ av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
+ LLDate next_update_local(next_update_local_secs);
+ // display as "July 18 12:17 PM"
+ std::string next_update_string =
+ next_update_local.toHTTPDateString("%B %d %I:%M %p");
+ getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
+ getChild<LLUICtrl>("lockout_text")->setVisible(true);
+ getChild<LLUICtrl>("save_btn")->setEnabled(false);
+ getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
+ getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
+ getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
+
+ }
+ else
+ {
+ getChild<LLUICtrl>("lockout_text")->setVisible(false);
+ getChild<LLUICtrl>("save_btn")->setEnabled(true);
+ getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
+ getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
+
+ }
+}
+
+BOOL LLFloaterDisplayName::postBuild()
+{
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
+ getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
+
+ center();
+
+ return TRUE;
+}
+
+void LLFloaterDisplayName::onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content)
+{
+ if (success)
+ {
+ // Inform the user that the change took place, but will take a while
+ // to percolate.
+ LLSD args;
+ args["DISPLAY_NAME"] = content["display_name"];
+ LLNotificationsUtil::add("SetDisplayNameSuccess", args);
+ return;
+ }
+
+ // Request failed, notify the user
+ std::string error_tag = content["error_tag"].asString();
+ LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
+
+ // We might have a localized string for this message
+ // error_args will usually be empty from the server.
+ if (!error_tag.empty()
+ && LLNotifications::getInstance()->templateExists(error_tag))
+ {
+ LLNotificationsUtil::add(error_tag);
+ return;
+ }
+
+ // The server error might have a localized message for us
+ std::string lang_code = LLUI::getLanguage();
+ LLSD error_desc = content["error_description"];
+ if (error_desc.has( lang_code ))
+ {
+ LLSD args;
+ args["MESSAGE"] = error_desc[lang_code].asString();
+ LLNotificationsUtil::add("GenericAlert", args);
+ return;
+ }
+
+ // No specific error, throw a generic one
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+}
+
+void LLFloaterDisplayName::onCancel()
+{
+ setVisible(false);
+}
+
+void LLFloaterDisplayName::onSave()
+{
+ std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
+ std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
+
+ if (display_name_utf8.compare(display_name_confirm))
+ {
+ LLNotificationsUtil::add("SetDisplayNameMismatch");
+ return;
+ }
+
+ const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
+ LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
+ if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
+ {
+ LLSD args;
+ args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
+ LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
+ return;
+ }
+
+ if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
+ {
+ LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+ }
+ else
+ {
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ }
+
+ setVisible(false);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectObjectUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterDisplayNameUtil::registerFloater()
+{
+ LLFloaterReg::add("display_name", "floater_display_name.xml",
+ &LLFloaterReg::build<LLFloaterDisplayName>);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl b/indra/newview/llfloaterdisplayname.h
index ca9ce3a2e1..a00bf56712 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl
+++ b/indra/newview/llfloaterdisplayname.h
@@ -1,9 +1,9 @@
/**
- * @file pointShadowBlur.glsl
+ * @file llfloaterdisplayname.h
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * 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
@@ -23,15 +23,16 @@
* $/LicenseInfo$
*/
-uniform samplerCube cube_map;
+#ifndef LLFLOATERDISPLAYNAME_H
+#define LLFLOATERDISPLAYNAME_H
-in vec3 to_vec;
-out vec4 fragColor;
-
-void main()
+namespace LLFloaterDisplayNameUtil
{
- vec4 vcol = texture(cube_map, to_vec);
- fragColor = vec4(vcol.rgb, 1.0);
+ // Register with LLFloaterReg
+ void registerFloater();
}
+
+
+#endif
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index 24673d5a7c..6e8143384a 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -665,6 +665,7 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
if (ctrl_action == ACTION_SAVE)
{
doApplyUpdateInventory(dayclone);
+ clearDirtyFlag();
}
else if (ctrl_action == ACTION_SAVEAS)
{
@@ -1523,7 +1524,7 @@ bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
void LLFloaterEditExtDayCycle::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
index a6640cc073..a3504ac6ee 100644
--- a/indra/newview/llfloaterevent.cpp
+++ b/indra/newview/llfloaterevent.cpp
@@ -108,11 +108,12 @@ void LLFloaterEvent::setEventID(const U32 event_id)
LLSD subs;
subs["EVENT_ID"] = (S32)event_id;
// get the search URL and expand all of the substitutions
- // (also adds things like [LANGUAGE], [VERSION], [OS], etc.)
- std::ostringstream url;
- url << gSavedSettings.getString("EventURL") << event_id << std::endl;
+ // (also adds things like [LANGUAGE], [VERSION], [OS], etc.)
+
+ std::string expanded_url = LLWeb::expandURLSubstitutions(gSavedSettings.getString("EventURL"), subs);
+
// and load the URL in the web view
- mBrowser->navigateTo(url.str());
+ mBrowser->navigateTo(expanded_url);
}
}
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index fec218ca3b..b9dc14ac1a 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -296,6 +296,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
if (ctrl_action == ACTION_SAVE)
{
doApplyUpdateInventory(setting_clone);
+ clearDirtyFlag();
}
else if (ctrl_action == ACTION_SAVEAS)
{
@@ -439,7 +440,7 @@ void LLFloaterFixedEnvironmentWater::onOpen(const LLSD& key)
void LLFloaterFixedEnvironmentWater::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile(const std::vector<std::string>& filenames)
@@ -525,7 +526,7 @@ void LLFloaterFixedEnvironmentSky::onClose(bool app_quitting)
void LLFloaterFixedEnvironmentSky::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterFixedEnvironmentSky::loadSkySettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterFixedEnvironmentSky::loadSkySettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterFixedEnvironmentSky::loadSkySettingFromFile(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 6e326ff3cf..d17889bed1 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -122,7 +122,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
mObserver = new LLFloaterGestureObserver(this);
LLGestureMgr::instance().addObserver(mObserver);
- mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.ToggleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2));
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
index 42c5e40761..a00fc4aa84 100644
--- a/indra/newview/llfloaterhoverheight.cpp
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -100,11 +100,14 @@ void LLFloaterHoverHeight::onClose(bool app_quitting)
// static
void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData)
{
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- F32 value = sldrCtrl->getValueF32();
- LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
- LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
- gAgentAvatarp->setHoverOffset(offset, false);
+ if (isAgentAvatarValid())
+ {
+ LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
+ F32 value = sldrCtrl->getValueF32();
+ LLVector3 offset(0.0, 0.0, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z));
+ LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
+ gAgentAvatarp->setHoverOffset(offset, false);
+ }
}
// Do send-to-the-server work when slider drag completes, or new
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 1525bb9952..703b5d0011 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -45,6 +45,7 @@
#include "llflashtimer.h"
#include "llfloateravatarpicker.h"
#include "llfloaterpreference.h"
+#include "llfloaterreporter.h"
#include "llimview.h"
#include "llnotificationsutil.h"
#include "lltoolbarview.h"
@@ -1242,6 +1243,18 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
{
LLAvatarActions::pay(userID);
}
+ else if ("report_abuse" == command)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(userID, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(userID, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(userID, "not avaliable");
+ }
+ }
else if ("block_unblock" == command)
{
LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat);
@@ -1507,7 +1520,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
}
// Handle all other options
- if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+ if (("can_invite" == item)
+ || ("can_chat_history" == item)
+ || ("can_share" == item)
+ || ("can_pay" == item)
+ || ("report_abuse" == item))
{
// Those menu items are enable only if a single avatar is selected
return is_single_select;
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 3a850d4b68..4cceddeefb 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -698,7 +698,6 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, ECha
void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
{
- LLUIUsage::instance().logCommand("Chat.Send"); // pseuo-command
// Look for "/20 foo" channel chats.
S32 channel = 0;
LLWString out_text = stripChannelNumber(wtext, &channel);
@@ -858,6 +857,12 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
{
+ LL_DEBUGS("UIUsage") << "Nearby chat, text " << utf8_out_text << " type " << type << " channel " << channel << LL_ENDL;
+ if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) // prune back some redundant logging
+ {
+ LLUIUsage::instance().logCommand("Chat.SendNearby"); // pseuo-command
+ }
+
LLMessageSystem* msg = gMessageSystem;
if (channel >= 0)
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 34499ac170..93a0b39e02 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -551,7 +551,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id)
{
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
- if (widget)
+ if (widget && widget->getViewModelItem())
{
widget->refresh();
}
@@ -576,8 +576,11 @@ void LLFloaterIMSessionTab::refreshConversation()
{
participants_uuids.push_back(widget_it->first);
}
- widget_it->second->refresh();
- widget_it->second->setVisible(TRUE);
+ if (widget_it->second->getViewModelItem())
+ {
+ widget_it->second->refresh();
+ widget_it->second->setVisible(TRUE);
+ }
++widget_it;
}
if (is_ad_hoc || mIsP2PChat)
@@ -1126,7 +1129,10 @@ void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
for (; it != it_end; ++it)
{
LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem());
- selected_uuids.push_back(conversation_item->getUUID());
+ if (conversation_item)
+ {
+ selected_uuids.push_back(conversation_item->getUUID());
+ }
}
}
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 93a26f31cc..558b14bba7 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -292,7 +292,7 @@ void LLFloaterJoystick::refreshListOfDevices()
std::string desc = LLViewerJoystick::getInstance()->getDescription();
if (!desc.empty())
{
- LLSD value = LLSD::Integer(0);
+ LLSD value = LLSD::Integer(1); // value for selection
addDevice(desc, value);
mHasDeviceList = true;
}
@@ -392,6 +392,9 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
LLSD value = self->mJoysticksCombo->getValue();
bool joystick_enabled = true;
+ // value is 0 for no device,
+ // 1 for a device on Mac (single device, no list support yet)
+ // binary packed guid for a device on windows (can have multiple devices)
if (value.isInteger())
{
// ndof already has a device selected, we are just setting it enabled or disabled
@@ -400,7 +403,7 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
else
{
LLViewerJoystick::getInstance()->initDevice(value);
- // else joystick is enabled, because combobox holds id of device
+ // else joystick is enabled, because combobox holds id of the device
joystick_enabled = true;
}
gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled);
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 04133f2710..1a98ab9d76 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -452,7 +452,8 @@ BOOL LLPanelLandGeneral::postBuild()
mEditDesc = getChild<LLTextEditor>("Description");
mEditDesc->setCommitOnFocusLost(TRUE);
- mEditDesc->setCommitCallback(onCommitAny, this);
+ mEditDesc->setCommitCallback(onCommitAny, this);
+ mEditDesc->setContentTrusted(false);
// No prevalidate function - historically the prevalidate function was broken,
// allowing residents to put in characters like U+2661 WHITE HEART SUIT, so
// preserve that ability.
@@ -749,6 +750,7 @@ void LLPanelLandGeneral::refresh()
BOOL can_edit_identity = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_IDENTITY);
mEditName->setEnabled(can_edit_identity);
mEditDesc->setEnabled(can_edit_identity);
+ mEditDesc->setParseURLs(!can_edit_identity);
BOOL can_edit_agent_only = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_NO_POWERS);
mBtnSetGroup->setEnabled(can_edit_agent_only && !parcel->getIsGroupOwned());
@@ -3054,7 +3056,8 @@ BOOL LLPanelLandCovenant::postBuild()
{
mLastRegionID = LLUUID::null;
mNextUpdateTime = 0;
-
+ mTextEstateOwner = getChild<LLTextBox>("estate_owner_text");
+ mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend);
return TRUE;
}
@@ -3162,8 +3165,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name)
LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
if (self)
{
- LLTextBox* editor = self->getChild<LLTextBox>("estate_owner_text");
- if (editor) editor->setText(name);
+ self->mTextEstateOwner->setText(name);
}
}
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 5d9b411f04..684950d88b 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -413,6 +413,7 @@ protected:
private:
LLUUID mLastRegionID;
F64 mNextUpdateTime; //seconds since client start
+ LLTextBox* mTextEstateOwner;
};
#endif
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index fc2da772f3..fd1af7ccc0 100644..100755
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -51,7 +51,7 @@
// The minor cardinal direction labels are hidden if their height is more
// than this proportion of the map.
-const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f;
+const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f;
//
// Member functions
@@ -77,35 +77,44 @@ LLFloaterMap::~LLFloaterMap()
BOOL LLFloaterMap::postBuild()
{
- mMap = getChild<LLNetMap>("Net Map");
- if (gSavedSettings.getBOOL("DoubleClickTeleport"))
- {
- mMap->setToolTipMsg(getString("AltToolTipMsg"));
- }
- else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
- {
- mMap->setToolTipMsg(getString("ToolTipMsg"));
- }
- sendChildToBack(mMap);
-
- mTextBoxNorth = getChild<LLTextBox> ("floater_map_north");
- mTextBoxEast = getChild<LLTextBox> ("floater_map_east");
- mTextBoxWest = getChild<LLTextBox> ("floater_map_west");
- mTextBoxSouth = getChild<LLTextBox> ("floater_map_south");
- mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast");
- mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast");
- mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
- mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
-
- updateMinorDirections();
-
- // Get the drag handle all the way in back
- sendChildToBack(getDragHandle());
-
- // keep onscreen
- gFloaterView->adjustToFitScreen(this, FALSE);
-
- return TRUE;
+ mMap = getChild<LLNetMap>("Net Map");
+ mMap->setToolTipMsg(getString("ToolTipMsg"));
+ mMap->setParcelNameMsg(getString("ParcelNameMsg"));
+ mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg"));
+ mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg"));
+ mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg"));
+ mMap->setRegionNameMsg(getString("RegionNameMsg"));
+ mMap->setToolTipHintMsg(getString("ToolTipHintMsg"));
+ mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg"));
+ sendChildToBack(mMap);
+
+ mTextBoxNorth = getChild<LLTextBox>("floater_map_north");
+ mTextBoxEast = getChild<LLTextBox>("floater_map_east");
+ mTextBoxWest = getChild<LLTextBox>("floater_map_west");
+ mTextBoxSouth = getChild<LLTextBox>("floater_map_south");
+ mTextBoxSouthEast = getChild<LLTextBox>("floater_map_southeast");
+ mTextBoxNorthEast = getChild<LLTextBox>("floater_map_northeast");
+ mTextBoxSouthWest = getChild<LLTextBox>("floater_map_southwest");
+ mTextBoxNorthWest = getChild<LLTextBox>("floater_map_northwest");
+
+ mTextBoxNorth->reshapeToFitText();
+ mTextBoxEast->reshapeToFitText();
+ mTextBoxWest->reshapeToFitText();
+ mTextBoxSouth->reshapeToFitText();
+ mTextBoxSouthEast->reshapeToFitText();
+ mTextBoxNorthEast->reshapeToFitText();
+ mTextBoxSouthWest->reshapeToFitText();
+ mTextBoxNorthWest->reshapeToFitText();
+
+ updateMinorDirections();
+
+ // Get the drag handle all the way in back
+ sendChildToBack(getDragHandle());
+
+ // keep onscreen
+ gFloaterView->adjustToFitScreen(this, false);
+
+ return true;
}
BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -138,23 +147,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
-void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
+void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation)
{
- // Rotation is in radians.
- // Rotation of 0 means x = 1, y = 0 on the unit circle.
-
- F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2;
- F32 map_half_width = (F32)(getRect().getWidth() / 2) ;
- F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2);
- F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2);
- F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width );
-
- // Inset by a little to account for position display.
- radius -= 8.f;
-
- text_box->setOrigin(
- ll_round(map_half_width - text_half_width + radius * cos( rotation )),
- ll_round(map_half_height - text_half_height + radius * sin( rotation )) );
+ // Rotation is in radians.
+ // Rotation of 0 means x = 1, y = 0 on the unit circle.
+
+ F32 map_half_height = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2);
+ F32 map_half_width = (F32) (getRect().getWidth() / 2);
+ F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2);
+ F32 text_half_width = (F32) (text_box->getRect().getWidth() / 2);
+ F32 extra_padding = (F32) (mTextBoxNorth->getRect().getWidth() / 2);
+ F32 pos_half_height = map_half_height - text_half_height - extra_padding;
+ F32 pos_half_width = map_half_width - text_half_width - extra_padding;
+
+ F32 corner_angle = atan2(pos_half_height, pos_half_width);
+ F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI));
+ if (rotation < 0)
+ {
+ rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top;
+ }
+ F32 rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO));
+ bool at_left_right_edge = rotation_mirrored_into_top_right < corner_angle;
+
+ F32 part_x = cos(rotation);
+ F32 part_y = sin(rotation);
+ F32 y;
+ F32 x;
+ if (at_left_right_edge)
+ {
+ x = std::copysign(pos_half_width, part_x);
+ y = x * part_y / part_x;
+ }
+ else
+ {
+ y = std::copysign(pos_half_height, part_y);
+ x = y * part_x / part_y;
+ }
+
+ text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height));
}
void LLFloaterMap::updateMinorDirections()
@@ -218,32 +248,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
updateMinorDirections();
}
-void LLFloaterMap::handleZoom(const LLSD& userdata)
-{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- mMap->setScale(scale);
- }
-}
-
LLFloaterMap* LLFloaterMap::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map");
diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h
index ff2fb20535..929b1795aa 100644
--- a/indra/newview/llfloatermap.h
+++ b/indra/newview/llfloatermap.h
@@ -48,7 +48,6 @@ public:
/*virtual*/ void draw();
private:
- void handleZoom(const LLSD& userdata);
void setDirectionPos( LLTextBox* text_box, F32 rotation );
void updateMinorDirections();
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 524162ba51..e755e9924c 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -579,7 +579,25 @@ void LLFloaterMarketplaceListings::updateView()
// Update the top message or flip to the tabs and folders view
// *TODO : check those messages and create better appropriate ones in strings.xml
- if (mRootFolderId.notNull())
+ if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)
+ {
+ std::string reason = LLMarketplaceData::instance().getSLMConnectionfailureReason();
+ if (reason.empty())
+ {
+ text = LLTrans::getString("InventoryMarketplaceConnectionError");
+ }
+ else
+ {
+ LLSD args;
+ args["[REASON]"] = reason;
+ text = LLTrans::getString("InventoryMarketplaceConnectionErrorReason", args);
+ }
+
+ title = LLTrans::getString("InventoryOutboxErrorTitle");
+ tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+ LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL;
+ }
+ else if (mRootFolderId.notNull())
{
// "Marketplace listings is empty!" message strings
text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs);
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index 2afd889609..b34961e8a2 100644
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -157,6 +157,18 @@ void LLFloaterMediaSettings::apply()
}
////////////////////////////////////////////////////////////////////////////////
+void LLFloaterMediaSettings::onOpen(const LLSD& key)
+{
+ if (mPanelMediaSettingsGeneral)
+ {
+ // media is expensive, so only load it when nessesary.
+ // If we need to preload it, set volume to 0 and any pause
+ // if applicable, then unpause here
+ mPanelMediaSettingsGeneral->updateMediaPreview();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
void LLFloaterMediaSettings::onClose(bool app_quitting)
{
if(mPanelMediaSettingsGeneral)
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
index f93512eb3a..151e43e6b9 100644
--- a/indra/newview/llfloatermediasettings.h
+++ b/indra/newview/llfloatermediasettings.h
@@ -42,6 +42,7 @@ public:
~LLFloaterMediaSettings();
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
static LLFloaterMediaSettings* getInstance();
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index fe5120376c..cba074b380 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -97,7 +97,7 @@ private:
};
LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
-: LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
+: LLFilePickerThread(LLFilePicker::FFLOAD_MODEL)
{
mMP = mp;
mLOD = lod;
@@ -330,8 +330,8 @@ void LLFloaterModelPreview::initModelPreview()
S32 tex_width = 512;
S32 tex_height = 512;
- S32 max_width = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mScreenWidth);
- S32 max_height = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mScreenHeight);
+ S32 max_width = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mRT->width);
+ S32 max_height = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mRT->height);
while ((tex_width << 1) < max_width)
{
@@ -467,22 +467,25 @@ void LLFloaterModelPreview::loadHighLodModel()
loadModel(3);
}
-void LLFloaterModelPreview::loadModel(S32 lod)
+void LLFloaterModelPreview::prepareToLoadModel(S32 lod)
{
mModelPreview->mLoading = true;
if (lod == LLModel::LOD_PHYSICS)
{
// loading physics from file
mModelPreview->mPhysicsSearchLOD = lod;
+ mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false;
}
-
+}
+void LLFloaterModelPreview::loadModel(S32 lod)
+{
+ prepareToLoadModel(lod);
(new LLMeshFilePicker(mModelPreview, lod))->getFile();
}
void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm)
{
- mModelPreview->mLoading = true;
-
+ prepareToLoadModel(lod);
mModelPreview->loadModel(file_name, lod, force_disable_slm);
}
@@ -507,6 +510,15 @@ void LLFloaterModelPreview::onClickCalculateBtn()
toggleCalculateButton(false);
mUploadBtn->setEnabled(false);
+
+ //disable "simplification" UI
+ LLPanel* simplification_panel = getChild<LLPanel>("physics simplification");
+ LLView* child = simplification_panel->getFirstChild();
+ while (child)
+ {
+ child->setEnabled(false);
+ child = simplification_panel->findNextSibling(child);
+ }
}
// Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function
@@ -741,7 +753,7 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
{
case LLModelPreview::MESH_OPTIMIZER_AUTO:
case LLModelPreview::MESH_OPTIMIZER_SLOPPY:
- case LLModelPreview::MESH_OPTIMIZER_COMBINE:
+ case LLModelPreview::MESH_OPTIMIZER_PRECISE:
mModelPreview->onLODMeshOptimizerParamCommit(lod, enforce_tri_limit, mode);
break;
default:
@@ -1063,11 +1075,18 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
}
S32 file_mode = iface->getItemCount() - 1;
- if (which_mode < file_mode)
+ S32 cube_mode = file_mode - 1;
+ if (which_mode < cube_mode)
{
S32 which_lod = num_lods - which_mode;
sInstance->mModelPreview->setPhysicsFromLOD(which_lod);
}
+ else if (which_mode == cube_mode)
+ {
+ std::string path = gDirUtilp->getAppRODataDir();
+ gDirUtilp->append(path, "cube.dae");
+ sInstance->loadModel(LLModel::LOD_PHYSICS, path);
+ }
LLModelPreview *model_preview = sInstance->mModelPreview;
if (model_preview)
@@ -1662,15 +1681,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod)
{
if (lod == LLModel::LOD_PHYSICS)
- {
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("physics_lod_combo");
if (lod_combo)
{
- lod_combo->setCurrentByIndex(5);
+ lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1);
}
}
else
-{
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);
if (lod_combo)
{
@@ -1745,7 +1764,7 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
S32 index = lod_source_combo->getCurrentIndex();
if (index == LLModelPreview::MESH_OPTIMIZER_AUTO
|| index == LLModelPreview::MESH_OPTIMIZER_SLOPPY
- || index == LLModelPreview::MESH_OPTIMIZER_COMBINE)
+ || index == LLModelPreview::MESH_OPTIMIZER_PRECISE)
{ //rebuild LoD to update triangle counts
onLODParamCommit(lod, true);
}
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 1e147cd555..bda042186b 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -221,6 +221,7 @@ private:
void resetUploadOptions();
void clearLogTab();
+ void prepareToLoadModel(S32 lod);
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index dccef88e41..ad5e97e067 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -42,7 +42,6 @@
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
-#include "llwebprofile.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index 87973c2286..94261b2e4e 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -72,7 +72,7 @@ struct LLGiveMoneyInfo
mFloater(floater), mAmount(amount){}
};
-typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
+typedef std::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
///----------------------------------------------------------------------------
/// Class LLFloaterPay
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 649a107d74..fb55c6c6c4 100644
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -123,6 +123,7 @@ const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
"Gestures",
"Wearables",
"Settings"
+ "Materials"
};
BOOL LLFloaterPermsDefault::postBuild()
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 70114df989..b3403fda0f 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -333,60 +333,59 @@ void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType t
const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData );
if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
{
- storeAvatarProperties( pAvatarData );
- processProfileProperties( pAvatarData );
+ mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
+ mAvatarDataInitialized = true;
+ getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);
}
}
}
-void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData )
+void LLFloaterPreference::saveAvatarProperties( void )
{
- if (LLStartUp::getStartupState() == STATE_STARTED)
- {
- mAvatarProperties.avatar_id = pAvatarData->avatar_id;
- mAvatarProperties.image_id = pAvatarData->image_id;
- mAvatarProperties.fl_image_id = pAvatarData->fl_image_id;
- mAvatarProperties.about_text = pAvatarData->about_text;
- mAvatarProperties.fl_about_text = pAvatarData->fl_about_text;
- mAvatarProperties.profile_url = pAvatarData->profile_url;
- mAvatarProperties.flags = pAvatarData->flags;
- mAvatarProperties.allow_publish = pAvatarData->flags & AVATAR_ALLOW_PUBLISH;
+ const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
- mAvatarDataInitialized = true;
- }
-}
+ if ((LLStartUp::getStartupState() == STATE_STARTED)
+ && mAvatarDataInitialized
+ && (allowPublish != mAllowPublish))
+ {
+ std::string cap_url = gAgent.getRegionCapability("AgentProfile");
+ if (!cap_url.empty())
+ {
+ mAllowPublish = allowPublish;
-void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData )
-{
- getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
+ }
+ }
}
-void LLFloaterPreference::saveAvatarProperties( void )
+void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
{
- const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
- if (allowPublish)
- {
- mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH;
- }
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
- //
- // NOTE: We really don't want to send the avatar properties unless we absolutely
- // need to so we can avoid the accidental profile reset bug, so, if we're
- // logged in, the avatar data has been initialized and we have a state change
- // for the "allow publish" flag, then set the flag to its new value and send
- // the properties update.
- //
- // NOTE: The only reason we can not remove this update altogether is because of the
- // "allow publish" flag, the last remaining profile setting in the viewer
- // that doesn't exist in the web profile.
- //
- if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish))
- {
- mAvatarProperties.allow_publish = allowPublish;
+ std::string finalUrl = cap_url + "/" + gAgentID.asString();
+ LLSD data;
+ data["allow_publish"] = allow_publish;
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties );
- }
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
}
BOOL LLFloaterPreference::postBuild()
@@ -400,6 +399,7 @@ BOOL LLFloaterPreference::postBuild()
gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this));
gSavedPerAccountSettings.getControl("ModelUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeModelFolder, this));
+ gSavedPerAccountSettings.getControl("PBRUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangePBRFolder, this));
gSavedPerAccountSettings.getControl("TextureUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeTextureFolder, this));
gSavedPerAccountSettings.getControl("SoundUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeSoundFolder, this));
gSavedPerAccountSettings.getControl("AnimationUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeAnimationFolder, this));
@@ -689,6 +689,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
onChangeMaturity();
onChangeModelFolder();
+ onChangePBRFolder();
onChangeTextureFolder();
onChangeSoundFolder();
onChangeAnimationFolder();
@@ -938,7 +939,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata)
else
{
// Show beep, pop up dialog, etc.
- LL_INFOS() << "Can't close preferences!" << LL_ENDL;
+ LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
}
LLPanelLogin::updateLocationSelectorsVisibility();
@@ -1180,30 +1181,10 @@ void LLFloaterPreference::buildPopupLists()
void LLFloaterPreference::refreshEnabledState()
{
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
- LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+ LLCheckBoxCtrl* ctrl_pbr = getChild<LLCheckBoxCtrl>("UsePBRShaders");
- // if vertex shaders off, disable all shader related products
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
- {
- ctrl_wind_light->setEnabled(FALSE);
- ctrl_wind_light->setValue(FALSE);
- }
- else
- {
- ctrl_wind_light->setEnabled(TRUE);
- }
-
- //Deferred/SSAO/Shadows
- BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
- BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
- bumpshiny &&
- shaders &&
- gGLManager.mHasFramebufferObject &&
- (ctrl_wind_light->get()) ? TRUE : FALSE;
-
- ctrl_deferred->setEnabled(enabled);
+ //PBR
+ ctrl_pbr->setEnabled(TRUE);
// Cannot have floater active until caps have been received
getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
@@ -1213,59 +1194,19 @@ void LLFloaterPreference::refreshEnabledState()
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
{
- LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
- LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
-
- // Reflections
- BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
- ctrl_reflections->setEnabled(reflections);
- reflections_text->setEnabled(reflections);
-
- // Bump & Shiny
- LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
- bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
- bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
-
- // Avatar Mode
- // Avatar Render Mode
- getChild<LLCheckBoxCtrl>("AvatarCloth")->setEnabled(TRUE);
-
- // Vertex Shaders, Global Shader Enable
- // SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code
- LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail"); // can be linked with control var
- LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText");
-
- terrain_detail->setEnabled(FALSE);
- terrain_text->setEnabled(FALSE);
-
// WindLight
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
- ctrl_wind_light->setEnabled(TRUE);
sky->setEnabled(TRUE);
sky_text->setEnabled(TRUE);
- //Deferred/SSAO/Shadows
- LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
-
- BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
- ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
- gGLManager.mHasFramebufferObject &&
- (ctrl_wind_light->get()) ? TRUE : FALSE;
-
- ctrl_deferred->setEnabled(enabled);
-
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText");
- // note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
- enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
+ BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO");
- ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
-
ctrl_ssao->setEnabled(enabled);
ctrl_dof->setEnabled(enabled);
@@ -1276,23 +1217,11 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
// Hardware settings
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
- !gGLManager.mHasVertexBufferObject)
- {
- getChildView("vbo")->setEnabled(FALSE);
- }
-
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
- !gGLManager.mHasVertexBufferObject)
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures"))
{
getChildView("texture compression")->setEnabled(FALSE);
}
- // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
- LLUICtrl* gamma_ctrl = getChild<LLUICtrl>("gamma");
- gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
- getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders());
- getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders());
getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"));
// now turn off any features that are unavailable
@@ -1343,11 +1272,6 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
{
- LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
- LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
- LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
- LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText");
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
@@ -1358,9 +1282,6 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
// disabled windlight
if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
{
- ctrl_wind_light->setEnabled(FALSE);
- ctrl_wind_light->setValue(FALSE);
-
sky->setEnabled(FALSE);
sky_text->setEnabled(FALSE);
@@ -1374,14 +1295,10 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
ctrl_dof->setEnabled(FALSE);
ctrl_dof->setValue(FALSE);
-
- ctrl_deferred->setEnabled(FALSE);
- ctrl_deferred->setValue(FALSE);
}
// disabled deferred
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
- !gGLManager.mHasFramebufferObject)
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"))
{
ctrl_shadows->setEnabled(FALSE);
ctrl_shadows->setValue(0);
@@ -1392,40 +1309,22 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
ctrl_dof->setEnabled(FALSE);
ctrl_dof->setValue(FALSE);
-
- ctrl_deferred->setEnabled(FALSE);
- ctrl_deferred->setValue(FALSE);
}
- // disabled deferred SSAO
+ // disabled deferred SSAO
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
{
- ctrl_ssao->setEnabled(FALSE);
+ ctrl_ssao->setEnabled(FALSE);
ctrl_ssao->setValue(FALSE);
}
// disabled deferred shadows
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
- {
- ctrl_shadows->setEnabled(FALSE);
- ctrl_shadows->setValue(0);
- shadows_text->setEnabled(FALSE);
- }
-
- // disabled reflections
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
- {
- ctrl_reflections->setEnabled(FALSE);
- ctrl_reflections->setValue(FALSE);
- reflections_text->setEnabled(FALSE);
- }
-
- // disabled cloth
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
- {
- ctrl_avatar_cloth->setEnabled(FALSE);
- ctrl_avatar_cloth->setValue(FALSE);
- }
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
+ {
+ ctrl_shadows->setEnabled(FALSE);
+ ctrl_shadows->setValue(0);
+ shadows_text->setEnabled(FALSE);
+ }
}
void LLFloaterPreference::refresh()
@@ -1788,13 +1687,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
if (!LLXMLNode::parseFile(filename, root, NULL))
{
- LL_WARNS() << "Unable to parse file " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
return false;
}
if (!root->hasName("labels"))
{
- LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
return false;
}
@@ -1814,7 +1713,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
}
else
{
- LL_WARNS() << filename << " failed to load" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
return false;
}
@@ -1884,6 +1783,14 @@ void LLFloaterPreference::onChangeModelFolder()
}
}
+void LLFloaterPreference::onChangePBRFolder()
+{
+ if (gInventory.isInventoryUsable())
+ {
+ getChild<LLTextBox>("upload_pbr")->setText(get_category_path(LLFolderType::FT_MATERIAL));
+ }
+}
+
void LLFloaterPreference::onChangeTextureFolder()
{
if (gInventory.isInventoryUsable())
@@ -2720,7 +2627,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2747,7 +2654,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2853,7 +2760,7 @@ void LLPanelPreferenceControls::populateControlTable()
{
// Either unknown mode or MODE_SAVED_SETTINGS
// It doesn't have UI or actual settings yet
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
// Searchable columns were removed, mark searchables for an update
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
@@ -2893,7 +2800,7 @@ void LLPanelPreferenceControls::populateControlTable()
}
else
{
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
}
// explicit update to make sure table is ready for llsearchableui
@@ -2948,10 +2855,15 @@ void LLPanelPreferenceControls::cancel()
if (mConflictHandler[i].hasUnsavedChanges())
{
mConflictHandler[i].clear();
+ if (mEditingMode == i)
+ {
+ // cancel() can be called either when preferences floater closes
+ // or when child floater closes (like advanced graphical settings)
+ // in which case we need to clear and repopulate table
+ regenerateControls();
+ }
}
}
- pControlsTable->clearRows();
- pControlsTable->clearColumns();
}
void LLPanelPreferenceControls::saveSettings()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 5ef2ca68d3..af17c46be0 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -100,9 +100,8 @@ public:
static void updateShowFavoritesCheckbox(bool val);
void processProperties( void* pData, EAvatarProcessorType type );
- void processProfileProperties(const LLAvatarData* pAvatarData );
- void storeAvatarProperties( const LLAvatarData* pAvatarData );
void saveAvatarProperties( void );
+ static void saveAvatarPropertiesCoro(const std::string url, bool allow_publish);
void selectPrivacyPanel();
void selectChatPanel();
void getControlNames(std::vector<std::string>& names);
@@ -174,6 +173,7 @@ public:
void applyResolution();
void onChangeMaturity();
void onChangeModelFolder();
+ void onChangePBRFolder();
void onChangeTextureFolder();
void onChangeSoundFolder();
void onChangeAnimationFolder();
@@ -213,7 +213,7 @@ private:
bool mOriginalHideOnlineStatus;
std::string mDirectoryVisibility;
- LLAvatarData mAvatarProperties;
+ bool mAllowPublish; // Allow showing agent in search
std::string mSavedCameraPreset;
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);
diff --git a/indra/newview/llfloaterprofile.cpp b/indra/newview/llfloaterprofile.cpp
new file mode 100644
index 0000000000..6ccdace6c5
--- /dev/null
+++ b/indra/newview/llfloaterprofile.cpp
@@ -0,0 +1,170 @@
+/**
+ * @file llfloaterprofile.cpp
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterprofile.h"
+
+#include "llagent.h" //gAgent
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+LLFloaterProfile::LLFloaterProfile(const LLSD& key)
+ : LLFloater(key),
+ mAvatarId(key["id"].asUUID()),
+ mNameCallbackConnection()
+{
+ mDefaultRectForGroup = false;
+}
+
+LLFloaterProfile::~LLFloaterProfile()
+{
+ if (mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection.disconnect();
+ }
+}
+
+void LLFloaterProfile::onOpen(const LLSD& key)
+{
+ mPanelProfile->onOpen(key);
+
+ // Update the avatar name.
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLFloaterProfile::postBuild()
+{
+ mPanelProfile = findChild<LLPanelProfile>(PANEL_PROFILE_VIEW);
+
+ return TRUE;
+}
+
+void LLFloaterProfile::onClickCloseBtn(bool app_quitting)
+{
+ if (!app_quitting)
+ {
+ if (mPanelProfile->hasUnpublishedClassifieds())
+ {
+ LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false));
+ }
+ else if (mPanelProfile->hasUnsavedChanges())
+ {
+ LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true));
+ }
+ else
+ {
+ closeFloater();
+ }
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (can_save)
+ {
+ // savable content
+
+ if (option == 0) // Save
+ {
+ mPanelProfile->commitUnsavedChanges();
+ closeFloater();
+ }
+ if (option == 1) // Discard
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+ else
+ {
+ // classifieds
+
+ if (option == 0) // Ok
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+
+}
+
+void LLFloaterProfile::createPick(const LLPickData &data)
+{
+ mPanelProfile->createPick(data);
+}
+
+void LLFloaterProfile::showPick(const LLUUID& pick_id)
+{
+ mPanelProfile->showPick(pick_id);
+}
+
+bool LLFloaterProfile::isPickTabSelected()
+{
+ return mPanelProfile->isPickTabSelected();
+}
+
+void LLFloaterProfile::refreshName()
+{
+ if (!mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+ }
+
+ LLPanelProfileSecondLife *panel = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife");
+ if (panel)
+ {
+ panel->refreshName();
+ }
+}
+
+void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit)
+{
+ mPanelProfile->showClassified(classified_id, edit);
+}
+
+void LLFloaterProfile::createClassified()
+{
+ mPanelProfile->createClassified();
+}
+
+void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mNameCallbackConnection.disconnect();
+ setTitle(av_name.getCompleteName());
+}
+
+// eof
diff --git a/indra/newview/llfloaterprofile.h b/indra/newview/llfloaterprofile.h
new file mode 100644
index 0000000000..b3ed02fc2c
--- /dev/null
+++ b/indra/newview/llfloaterprofile.h
@@ -0,0 +1,66 @@
+/**
+ * @file llfloaterprofile.h
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPROFILE_H
+#define LL_LLFLOATERPROFILE_H
+
+#include "llavatarnamecache.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llfloater.h"
+
+class LLPanelProfile;
+
+class LLFloaterProfile : public LLFloater
+{
+ LOG_CLASS(LLFloaterProfile);
+public:
+ LLFloaterProfile(const LLSD& key);
+ virtual ~LLFloaterProfile();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+ void onClickCloseBtn(bool app_quitting = false) override;
+ void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save);
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ void refreshName();
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+private:
+ LLAvatarNameCache::callback_connection_t mNameCallbackConnection;
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ LLPanelProfile* mPanelProfile;
+
+ LLUUID mAvatarId;
+};
+
+#endif // LL_LLFLOATERPROFILE_H
diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp
new file mode 100644
index 0000000000..bf1f56a6d1
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.cpp
@@ -0,0 +1,223 @@
+/**
+ * @file llfloaterprofiletexture.cpp
+ * @brief LLFloaterProfileTexture class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterprofiletexture.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "llpreview.h" // fors constants
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "lltextureview.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+
+
+LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner)
+ : LLFloater(LLSD())
+ , mUpdateDimensions(TRUE)
+ , mLastHeight(0)
+ , mLastWidth(0)
+ , mImage(NULL)
+ , mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
+ , mOwnerHandle(owner->getHandle())
+{
+ buildFromFile("floater_profile_texture.xml");
+}
+
+LLFloaterProfileTexture::~LLFloaterProfileTexture()
+{
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+
+// virtual
+BOOL LLFloaterProfileTexture::postBuild()
+{
+ mProfileIcon = getChild<LLIconCtrl>("profile_pic");
+
+ mCloseButton = getChild<LLButton>("close_btn");
+ mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
+
+ return TRUE;
+}
+
+// virtual
+void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLFloater::reshape(width, height, called_from_parent);
+}
+
+// It takes a while until we get height and width information.
+// When we receive it, reshape the window accordingly.
+void LLFloaterProfileTexture::updateDimensions()
+{
+ if (mImage.isNull())
+ {
+ return;
+ }
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ return;
+ }
+
+ S32 img_width = mImage->getFullWidth();
+ S32 img_height = mImage->getFullHeight();
+
+ if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED
+ || mLastWidth != img_width
+ || mLastHeight != img_height)
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ // Asset has been fully loaded
+ mUpdateDimensions = TRUE;
+ }
+
+ mLastHeight = img_height;
+ mLastWidth = img_width;
+
+ // Reshape the floater only when required
+ if (mUpdateDimensions)
+ {
+ mUpdateDimensions = FALSE;
+
+ LLRect old_floater_rect = getRect();
+ LLRect old_image_rect = mProfileIcon->getRect();
+ S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth;
+ S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight;
+
+ const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256
+
+ S32 biggest_dim = llmax(width, height);
+ if (biggest_dim > MAX_DIMENTIONS)
+ {
+ F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim;
+ width *= scale_down;
+ height *= scale_down;
+ }
+
+ //reshape floater
+ reshape(width, height);
+
+ gFloaterView->adjustToFitScreen(this, FALSE);
+ }
+}
+
+void LLFloaterProfileTexture::draw()
+{
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+
+ LLFloater::draw();
+}
+
+void LLFloaterProfileTexture::onOpen(const LLSD& key)
+{
+ mCloseButton->setFocus(true);
+}
+
+void LLFloaterProfileTexture::resetAsset()
+{
+ mProfileIcon->setValue("Generic_Person_Large");
+ mImageID = LLUUID::null;
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
+{
+ if (mImageID != image_id)
+ {
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ mProfileIcon->setValue(image_id);
+ mImageID = image_id;
+ mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mImageOldBoostLevel = mImage->getBoostLevel();
+
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded,
+ 0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList);
+
+ mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING;
+ }
+ else
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ }
+
+ mUpdateDimensions = TRUE;
+ updateDimensions();
+}
+
+// static
+void LLFloaterProfileTexture::onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get());
+ if (floater && success)
+ {
+ floater->mUpdateDimensions = TRUE;
+ floater->updateDimensions();
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
diff --git a/indra/newview/llfloaterprofiletexture.h b/indra/newview/llfloaterprofiletexture.h
new file mode 100644
index 0000000000..66a61213dd
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.h
@@ -0,0 +1,81 @@
+/**
+ * @file llfloaterprofiletexture.h
+ * @brief LLFloaterProfileTexture class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPROFILETEXTURE_H
+#define LL_LLFLOATERPROFILETEXTURE_H
+
+#include "llfloater.h"
+#include "llviewertexture.h"
+
+class LLButton;
+class LLImageRaw;
+class LLIconCtrl;
+
+class LLFloaterProfileTexture : public LLFloater
+{
+public:
+ LLFloaterProfileTexture(LLView* owner);
+ ~LLFloaterProfileTexture();
+
+ void draw() override;
+ void onOpen(const LLSD& key) override;
+
+ void resetAsset();
+ void loadAsset(const LLUUID &image_id);
+
+
+ static void onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
+protected:
+ BOOL postBuild() override;
+
+private:
+ void updateDimensions();
+
+ LLUUID mImageID;
+ LLPointer<LLViewerFetchedTexture> mImage;
+ S32 mImageOldBoostLevel;
+ S32 mAssetStatus;
+ F32 mContextConeOpacity;
+ S32 mLastHeight;
+ S32 mLastWidth;
+ BOOL mUpdateDimensions;
+
+ LLHandle<LLView> mOwnerHandle;
+ LLIconCtrl* mProfileIcon;
+ LLButton* mCloseButton;
+
+ LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
+};
+#endif // LL_LLFLOATERPROFILETEXTURE_H
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 19080f05c0..07d4dcae38 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -47,6 +47,7 @@
#include "llagent.h"
#include "llappviewer.h"
+#include "llavataractions.h"
#include "llavatarname.h"
#include "llfloateravatarpicker.h"
#include "llbutton.h"
@@ -1322,6 +1323,7 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data)
BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
{
+ static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024;
for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
{
std::string buffer;
@@ -1343,17 +1345,19 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
return FALSE;
}
- if (width > 512 || height > 512)
+ if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE)
{
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_SIZE_X"] = width;
args["TEXTURE_SIZE_Y"] = height;
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainSize", args);
return FALSE;
@@ -1826,7 +1830,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
setCtrlsEnabled(god || owner || manager);
getChildView("apply_btn")->setEnabled(FALSE);
-
+ getChildView("estate_owner")->setEnabled(TRUE);
getChildView("message_estate_btn")->setEnabled(god || owner || manager);
getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
@@ -1888,6 +1892,8 @@ BOOL LLPanelEstateInfo::postBuild()
getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE);
+ getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend);
+
return LLPanelRegionInfo::postBuild();
}
@@ -2108,6 +2114,8 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text");
region_landtype->setText(region->getLocalizedSimProductName());
+
+ getChild<LLButton>("reset_covenant")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate()));
// let the parent class handle the general data collection.
bool rv = LLPanelRegionInfo::refreshFromRegion(region);
@@ -2132,6 +2140,7 @@ BOOL LLPanelEstateCovenant::postBuild()
{
mEstateNameText = getChild<LLTextBox>("estate_name_text");
mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
+ mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend);
mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
mEditor = getChild<LLViewerTextEditor>("covenant_editor");
LLButton* reset_button = getChild<LLButton>("reset_covenant");
@@ -3681,7 +3690,7 @@ void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::strin
if (!search_string.empty())
{
listCtrl->setSearchColumn(0); // name column
- listCtrl->selectItemByPrefix(search_string, FALSE);
+ listCtrl->searchItems(search_string, false, true);
}
else
{
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index b73755cf4e..2df4ca973d 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -54,6 +54,7 @@
#include "llbutton.h"
#include "llfloaterreg.h"
#include "lltexturectrl.h"
+#include "lltexteditor.h"
#include "llscrolllistctrl.h"
#include "lldispatcher.h"
#include "llviewerobject.h"
@@ -250,9 +251,6 @@ LLFloaterReporter::~LLFloaterReporter()
mPosition.setVec(0.0f, 0.0f, 0.0f);
- std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );
- mMCDList.clear();
-
delete mResourceDatap;
}
@@ -661,6 +659,23 @@ void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::strin
show(avatar_id, avatar_name);
}
+// static
+void LLFloaterReporter::showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description)
+{
+ show(avatar_id, avatar_name);
+
+ LLStringUtil::format_map_t args;
+ args["[MSG_TIME]"] = time;
+ args["[MSG_DESCRIPTION]"] = description;
+
+ LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
+ if (self)
+ {
+ std::string description = self->getString("chat_report_format", args);
+ self->getChild<LLUICtrl>("details_edit")->setValue(description);
+ }
+}
+
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
{
getChild<LLUICtrl>("object_name")->setValue(object_name);
@@ -1028,37 +1043,3 @@ void LLFloaterReporter::onClose(bool app_quitting)
mSnapshotTimer.stop();
gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);
}
-
-
-// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
-// if (self)
-// {
-// self->getChild<LLUICtrl>("details_edit")->setValue(description);
-
-// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer());
-// self->mMCDList.clear();
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
-
-// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
-// if (self)
-// {
-// LLTextEditor* text = self->getChild<LLTextEditor>("details_edit");
-// if (text)
-// {
-// text->insertText(description);
-// }
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index c678df7155..b6c70e866d 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -93,6 +93,7 @@ public:
static void showFromObject(const LLUUID& object_id, const LLUUID& experience_id = LLUUID::null);
static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);
+ static void showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description);
static void showFromExperience(const LLUUID& experience_id);
static void onClickSend (void *userdata);
@@ -101,8 +102,6 @@ public:
void onClickSelectAbuser ();
static void closePickTool (void *userdata);
static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status);
- static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
- static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);
@@ -114,10 +113,8 @@ private:
static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null);
void takeScreenshot(bool use_prev_screenshot = false);
- void sendReportViaCaps(std::string url);
void uploadImage();
bool validateReport();
- void setReporterID();
LLSD gatherReport();
void sendReportViaLegacy(const LLSD & report);
void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);
@@ -144,7 +141,6 @@ private:
BOOL mPicking;
LLVector3 mPosition;
BOOL mCopyrightWarningSeen;
- std::list<LLMeanCollisionData*> mMCDList;
std::string mDefaultSummary;
LLResourceData* mResourceDatap;
boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 2e1fbb09e0..bb3ed77772 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -57,10 +57,10 @@ public:
const size_t parts = tokens.size();
// get the (optional) category for the search
- std::string category;
+ std::string collection;
if (parts > 0)
{
- category = tokens[0].asString();
+ collection = tokens[0].asString();
}
// get the (optional) search string
@@ -72,7 +72,7 @@ public:
// create the LLSD arguments for the search floater
LLFloaterSearch::Params p;
- p.search.category = category;
+ p.search.collection = collection;
p.search.query = LLURI::unescape(search_text);
// open the search floater and perform the requested search
@@ -83,8 +83,9 @@ public:
LLSearchHandler gSearchHandler;
LLFloaterSearch::SearchQuery::SearchQuery()
-: category("category", ""),
- query("query")
+: category("category", ""),
+ collection("collection", ""),
+ query("query")
{}
LLFloaterSearch::LLFloaterSearch(const Params& key) :
@@ -93,16 +94,16 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) :
{
// declare a map that transforms a category name into
// the URL suffix that is used to search that category
- mCategoryPaths = LLSD::emptyMap();
- mCategoryPaths["all"] = "search";
- mCategoryPaths["people"] = "search/people";
- mCategoryPaths["places"] = "search/places";
- mCategoryPaths["events"] = "search/events";
- mCategoryPaths["groups"] = "search/groups";
- mCategoryPaths["wiki"] = "search/wiki";
- mCategoryPaths["land"] = "land";
- mCategoryPaths["destinations"] = "destinations";
- mCategoryPaths["classifieds"] = "classifieds";
+
+ mSearchType.insert("standard");
+ mSearchType.insert("land");
+ mSearchType.insert("classified");
+
+ mCollectionType.insert("events");
+ mCollectionType.insert("destinations");
+ mCollectionType.insert("places");
+ mCollectionType.insert("groups");
+ mCollectionType.insert("people");
}
BOOL LLFloaterSearch::postBuild()
@@ -157,31 +158,49 @@ void LLFloaterSearch::search(const SearchQuery &p)
// work out the subdir to use based on the requested category
LLSD subs;
- if (mCategoryPaths.has(p.category))
+ if (mSearchType.find(p.category) != mSearchType.end())
{
- subs["CATEGORY"] = mCategoryPaths[p.category].asString();
+ subs["TYPE"] = p.category;
}
else
{
- subs["CATEGORY"] = mCategoryPaths["all"].asString();
+ subs["TYPE"] = "standard";
}
// add the search query string
subs["QUERY"] = LLURI::escape(p.query);
+ subs["COLLECTION"] = "";
+ if (subs["TYPE"] == "standard")
+ {
+ if (mCollectionType.find(p.collection) != mCollectionType.end())
+ {
+ subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection);
+ }
+ else
+ {
+ std::string collection_args("");
+ for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it)
+ {
+ collection_args += "&collection_chosen=" + std::string(*it);
+ }
+ subs["COLLECTION"] = collection_args;
+ }
+ }
+
// add the user's preferred maturity (can be changed via prefs)
std::string maturity;
if (gAgent.prefersAdult())
{
- maturity = "42"; // PG,Mature,Adult
+ maturity = "gma"; // PG,Mature,Adult
}
else if (gAgent.prefersMature())
{
- maturity = "21"; // PG,Mature
+ maturity = "gm"; // PG,Mature
}
else
{
- maturity = "13"; // PG
+ maturity = "g"; // PG
}
subs["MATURITY"] = maturity;
diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h
index 35b268e1b2..cc77ce696f 100644
--- a/indra/newview/llfloatersearch.h
+++ b/indra/newview/llfloatersearch.h
@@ -49,6 +49,7 @@ public:
struct SearchQuery : public LLInitParam::Block<SearchQuery>
{
Optional<std::string> category;
+ Optional<std::string> collection;
Optional<std::string> query;
SearchQuery();
@@ -84,7 +85,8 @@ public:
private:
/*virtual*/ BOOL postBuild();
- LLSD mCategoryPaths;
+ std::set<std::string> mSearchType;
+ std::set<std::string> mCollectionType;
U8 mSearchGodLevel;
};
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
index de5d59f484..32eb70cd39 100644
--- a/indra/newview/llfloaterspellchecksettings.cpp
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -259,7 +259,7 @@ BOOL LLFloaterSpellCheckerImport::postBuild(void)
void LLFloaterSpellCheckerImport::onBtnBrowse()
{
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false);
}
void LLFloaterSpellCheckerImport::importSelectedDictionary(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 0429749e11..b6acba6558 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -46,7 +46,6 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
-#include "llmediactrl.h"
#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llpanelcontents.h"
@@ -240,7 +239,6 @@ BOOL LLFloaterTools::postBuild()
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
mBtnGridOptions = getChild<LLButton>("Options...");
- mTitleMedia = getChild<LLMediaCtrl>("title_media");
mBtnLink = getChild<LLButton>("link_btn");
mBtnUnlink = getChild<LLButton>("unlink_btn");
@@ -329,7 +327,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCheckSnapToGrid(NULL),
mBtnGridOptions(NULL),
- mTitleMedia(NULL),
mComboGridMode(NULL),
mCheckStretchUniform(NULL),
mCheckStretchTexture(NULL),
@@ -369,8 +366,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mLandImpactsObserver(NULL),
mDirty(TRUE),
- mHasSelection(TRUE),
- mNeedMediaTitle(TRUE)
+ mHasSelection(TRUE)
{
gFloaterTools = this;
@@ -394,9 +390,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
- mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
@@ -480,30 +473,61 @@ void LLFloaterTools::refresh()
else
#endif
{
- F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost();
- S32 link_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ F32 link_cost = selection->getSelectedLinksetCost();
+ S32 link_count = selection->getRootObjectCount();
+ S32 object_count = selection->getObjectCount();
- LLCrossParcelFunctor func;
- if (LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
- {
- // Selection crosses parcel bounds.
- // We don't display remaining land capacity in this case.
- const LLStringExplicit empty_str("");
- childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str);
- }
- else
- {
- LLViewerObject* selected_object = mObjectSelection->getFirstObject();
- if (selected_object)
- {
- // Select a parcel at the currently selected object's position.
- LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
- }
- else
- {
- LL_WARNS() << "Failed to get selected object" << LL_ENDL;
- }
- }
+ LLCrossParcelFunctor func;
+ if (!LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
+ {
+ // Unless multiple parcels selected, higlight parcel object is at.
+ LLViewerObject* selected_object = mObjectSelection->getFirstObject();
+ if (selected_object)
+ {
+ // Select a parcel at the currently selected object's position.
+ LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
+ }
+ else
+ {
+ LL_WARNS() << "Failed to get selected object" << LL_ENDL;
+ }
+ }
+
+ if (object_count == 1)
+ {
+ // "selection_faces" shouldn't be visible if not LLToolFace::getInstance()
+ // But still need to be populated in case user switches
+
+ std::string faces_str = "";
+
+ for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end();)
+ {
+ LLObjectSelection::iterator nextiter = iter++; // not strictly needed, we have only one object
+ LLSelectNode* node = *nextiter;
+ LLViewerObject* object = (*nextiter)->getObject();
+ if (!object)
+ continue;
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ if (!faces_str.empty())
+ {
+ faces_str += ", ";
+ }
+ faces_str += llformat("%d", te);
+ }
+ }
+ }
+
+ childSetTextArg("selection_faces", "[FACES_STRING]", faces_str);
+ }
+
+ bool show_faces = (object_count == 1)
+ && LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ getChildView("selection_faces")->setVisible(show_faces);
LLStringUtil::format_map_t selection_args;
selection_args["OBJ_COUNT"] = llformat("%.1d", link_count);
@@ -522,7 +546,7 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
- refreshMedia();
+ mPanelFace->refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
@@ -549,9 +573,6 @@ void LLFloaterTools::draw()
mDirty = FALSE;
}
- // grab media name/title and update the UI widget
- updateMediaTitle();
-
// mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
LLFloater::draw();
}
@@ -824,7 +845,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
getChildView("selection_count")->setVisible(!land_visible && have_selection);
- getChildView("remaining_capacity")->setVisible(!land_visible && have_selection);
+ getChildView("selection_faces")->setVisible(LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()
+ && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1);
getChildView("selection_empty")->setVisible(!land_visible && !have_selection);
mTab->setVisible(!land_visible);
@@ -874,8 +896,7 @@ void LLFloaterTools::onClose(bool app_quitting)
LLViewerJoystick::getInstance()->moveAvatar(false);
// destroy media source used to grab media title
- if( mTitleMedia )
- mTitleMedia->unloadMediaSource();
+ mPanelFace->unloadMedia();
// Different from handle_reset_view in that it doesn't actually
// move the camera if EditCameraMovement is not set.
@@ -1095,7 +1116,7 @@ void LLFloaterTools::onClickGridOptions()
{
LLFloater* floaterp = LLFloaterReg::showInstance("build_options");
// position floater next to build tools, not over
- floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp));
+ floaterp->setShape(gFloaterView->findNeighboringPosition(this, floaterp), true);
}
// static
@@ -1128,51 +1149,6 @@ void LLFloaterTools::onFocusReceived()
LLFloater::onFocusReceived();
}
-// Media stuff
-void LLFloaterTools::refreshMedia()
-{
- getMediaState();
-}
-
-bool LLFloaterTools::selectedMediaEditable()
-{
- U32 owner_mask_on;
- U32 owner_mask_off;
- U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,
- &owner_mask_on, &owner_mask_off );
- U32 group_mask_on;
- U32 group_mask_off;
- U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,
- &group_mask_on, &group_mask_off );
- U32 everyone_mask_on;
- U32 everyone_mask_off;
- S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,
- &everyone_mask_on, &everyone_mask_off );
-
- bool selected_Media_editable = false;
-
- // if perms we got back are valid
- if ( valid_owner_perms &&
- valid_group_perms &&
- valid_everyone_perms )
- {
-
- if ( ( owner_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) )
- {
- selected_Media_editable = true;
- }
- else
- // user is NOT allowed to press the RESET button
- {
- selected_Media_editable = false;
- };
- };
-
- return selected_Media_editable;
-}
-
void LLFloaterTools::updateLandImpacts()
{
LLParcel *parcel = mParcelSelection->getParcel();
@@ -1181,26 +1157,6 @@ void LLFloaterTools::updateLandImpacts()
return;
}
- S32 rezzed_prims = parcel->getSimWidePrimCount();
- S32 total_capacity = parcel->getSimWideMaxPrimCapacity();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- if (region)
- {
- S32 max_tasks_per_region = (S32)region->getMaxTasks();
- total_capacity = llmin(total_capacity, max_tasks_per_region);
- }
- std::string remaining_capacity_str = "";
-
- bool show_mesh_cost = gMeshRepo.meshRezEnabled();
- if (show_mesh_cost)
- {
- LLStringUtil::format_map_t remaining_capacity_args;
- remaining_capacity_args["LAND_CAPACITY"] = llformat("%d", total_capacity - rezzed_prims);
- remaining_capacity_str = getString("status_remaining_capacity", remaining_capacity_args);
- }
-
- childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", remaining_capacity_str);
-
// Update land impacts info in the weights floater
LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::findTypedInstance<LLFloaterObjectWeights>("object_weights");
if(object_weights_floater)
@@ -1209,784 +1165,3 @@ void LLFloaterTools::updateLandImpacts()
}
}
-void LLFloaterTools::getMediaState()
-{
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- LLViewerObject* first_object = selected_objects->getFirstObject();
- LLTextBox* media_info = getChild<LLTextBox>("media_info");
-
- if( !(first_object
- && first_object->getPCode() == LL_PCODE_VOLUME
- &&first_object->permModify()
- ))
- {
- getChildView("add_media")->setEnabled(FALSE);
- media_info->clear();
- clearMediaSettings();
- return;
- }
-
- std::string url = first_object->getRegion()->getCapability("ObjectMedia");
- bool has_media_capability = (!url.empty());
-
- if(!has_media_capability)
- {
- getChildView("add_media")->setEnabled(FALSE);
- LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
- clearMediaSettings();
- return;
- }
-
- BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
- && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
- || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
- bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
-
- // Check modify permissions and whether any selected objects are in
- // the process of being fetched. If they are, then we're not editable
- if (editable)
- {
- LLObjectSelection::iterator iter = selected_objects->begin();
- LLObjectSelection::iterator end = selected_objects->end();
- for ( ; iter != end; ++iter)
- {
- LLSelectNode* node = *iter;
- LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
- if (NULL != object)
- {
- if (!object->permModify())
- {
- LL_INFOS("LLFloaterToolsMedia")
- << "Selection not editable due to lack of modify permissions on object id "
- << object->getID() << LL_ENDL;
-
- editable = false;
- break;
- }
- // XXX DISABLE this for now, because when the fetch finally
- // does come in, the state of this floater doesn't properly
- // update. Re-selecting fixes the problem, but there is
- // contention as to whether this is a sufficient solution.
-// if (object->isMediaDataBeingFetched())
-// {
-// LL_INFOS("LLFloaterToolsMedia")
-// << "Selection not editable due to media data being fetched for object id "
-// << object->getID() << LL_ENDL;
-//
-// editable = false;
-// break;
-// }
- }
- }
- }
-
- // Media settings
- bool bool_has_media = false;
- struct media_functor : public LLSelectedTEGetFunctor<bool>
- {
- bool get(LLViewerObject* object, S32 face)
- {
- LLTextureEntry *te = object->getTE(face);
- if (te)
- {
- return te->hasMedia();
- }
- return false;
- }
- } func;
-
-
- // check if all faces have media(or, all dont have media)
- LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
-
- const LLMediaEntry default_media_data;
-
- struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
- {
- functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- LLMediaEntry get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return *(object->getTE(face)->getMediaData());
- return mMediaEntry;
- };
-
- const LLMediaEntry& mMediaEntry;
-
- } func_media_data(default_media_data);
-
- LLMediaEntry media_data_get;
- LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get ));
-
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- std::string media_title = "";
- // update UI depending on whether "object" (prim or face) has media
- // and whether or not you are allowed to edit it.
-
- getChildView("add_media")->setEnabled(editable);
- // IF all the faces have media (or all dont have media)
- if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
- {
- // TODO: get media title and set it.
- media_info->clear();
- // if identical is set, all faces are same (whether all empty or has the same media)
- if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) )
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- // else all faces might be empty.
- }
- else // there' re Different Medias' been set on on the faces.
- {
- media_title = multi_media_info_str;
- }
-
- getChildView("delete_media")->setEnabled(bool_has_media && 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.
- {
- // seleted faces have not identical value
- LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data );
-
- if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
- {
- media_title = multi_media_info_str;
- }
- else
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- }
-
- getChildView("delete_media")->setEnabled(TRUE);
- }
-
- navigateToTitleMedia(media_title);
- media_info->setText(media_title);
-
- // load values for media settings
- updateMediaSettings();
-
- LLFloaterMediaSettings::initValues(mMediaSettings, editable );
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to add media to a prim or prim face
-void LLFloaterTools::onClickBtnAddMedia()
-{
- // check if multiple faces are selected
- if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
- {
- LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
- }
- else
- {
- onClickBtnEditMedia();
- }
-}
-
-// static
-bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- gFloaterTools->onClickBtnEditMedia();
- break;
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to edit existing media settings on a prim or prim face
-// TODO: test if there is media on the item and only allow editing if present
-void LLFloaterTools::onClickBtnEditMedia()
-{
- refreshMedia();
- LLFloaterReg::showInstance("media_settings");
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to delete media from a prim or prim face
-void LLFloaterTools::onClickBtnDeleteMedia()
-{
- LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
-}
-
-
-// static
-bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() );
- if(LLFloaterReg::instanceVisible("media_settings"))
- {
- LLFloaterReg::hideInstance("media_settings");
- }
- break;
-
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::clearMediaSettings()
-{
- LLFloaterMediaSettings::clearValues(false);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::navigateToTitleMedia( const std::string url )
-{
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- if (url.empty() || multi_media_info_str == url)
- {
- // nothing to show
- mNeedMediaTitle = false;
- }
- else if (mTitleMedia)
- {
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
-
- if ( media_plugin ) // Shouldn't this be after navigateTo creates plugin?
- {
- // if it's a movie, we don't want to hear it
- media_plugin->setVolume( 0 );
- };
-
- // check if url changed or if we need a new media source
- if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
- {
- mTitleMedia->navigateTo( url );
- }
-
- // flag that we need to update the title (even if no request were made)
- mNeedMediaTitle = true;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaTitle()
-{
- // only get the media name if we need it
- if ( ! mNeedMediaTitle )
- return;
-
- // get plugin impl
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
- if ( media_plugin )
- {
- // get the media name (asynchronous - must call repeatedly)
- std::string media_title = media_plugin->getMediaName();
-
- // only replace the title if what we get contains something
- if ( ! media_title.empty() )
- {
- // update the UI widget
- LLTextBox* media_title_field = getChild<LLTextBox>("media_info");
- if ( media_title_field )
- {
- media_title_field->setText( media_title );
-
- // stop looking for a title when we get one
- // FIXME: check this is the right approach
- mNeedMediaTitle = false;
- };
- };
- };
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaSettings()
-{
- bool identical( false );
- std::string base_key( "" );
- std::string value_str( "" );
- int value_int = 0;
- bool value_bool = false;
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- // TODO: (CP) refactor this using something clever or boost or both !!
-
- const LLMediaEntry default_media_data;
-
- // controls
- U8 value_u8 = default_media_data.getControls();
- struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
- {
- functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
-
- U8 get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getControls();
- return mMediaEntry.getControls();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_controls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
- base_key = std::string( LLMediaEntry::CONTROLS_KEY );
- mMediaSettings[ base_key ] = value_u8;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // First click (formerly left click)
- value_bool = default_media_data.getFirstClickInteract();
- struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getFirstClickInteract();
- return mMediaEntry.getFirstClickInteract();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_first_click(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
- base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Home URL
- value_str = default_media_data.getHomeURL();
- struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHomeURL();
- return mMediaEntry.getHomeURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_home_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
- base_key = std::string( LLMediaEntry::HOME_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Current URL
- value_str = default_media_data.getCurrentURL();
- struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getCurrentURL();
- return mMediaEntry.getCurrentURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_current_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
- base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto zoom
- value_bool = default_media_data.getAutoZoom();
- struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
- {
-
- functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoZoom();
- return mMediaEntry.getAutoZoom();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_zoom(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto play
- //value_bool = default_media_data.getAutoPlay();
- // set default to auto play TRUE -- angela EXT-5172
- value_bool = true;
- struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoPlay();
- //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_play(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
-
- // Auto scale
- // set default to auto scale TRUE -- angela EXT-5172
- //value_bool = default_media_data.getAutoScale();
- value_bool = true;
- struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoScale();
- // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_scale(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto loop
- value_bool = default_media_data.getAutoLoop();
- struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoLoop();
- return mMediaEntry.getAutoLoop();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_loop(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // width pixels (if not auto scaled)
- value_int = default_media_data.getWidthPixels();
- struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWidthPixels();
- return mMediaEntry.getWidthPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_width_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
- base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // height pixels (if not auto scaled)
- value_int = default_media_data.getHeightPixels();
- struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHeightPixels();
- return mMediaEntry.getHeightPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_height_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
- base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Enable Alt image
- value_bool = default_media_data.getAltImageEnable();
- struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAltImageEnable();
- return mMediaEntry.getAltImageEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_enable_alt_image(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
- base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_control(default_media_data);
- identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_interact(default_media_data);
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist enable
- value_bool = default_media_data.getWhiteListEnable();
- struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteListEnable();
- return mMediaEntry.getWhiteListEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_enable(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
- base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist URLs
- std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
- struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
- {
- functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::vector<std::string> get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteList();
- return mMediaEntry.getWhiteList();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_urls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
- base_key = std::string( LLMediaEntry::WHITELIST_KEY );
- mMediaSettings[ base_key ].clear();
- std::vector< std::string >::iterator iter = value_vector_str.begin();
- while( iter != value_vector_str.end() )
- {
- std::string white_list_url = *iter;
- mMediaSettings[ base_key ].append( white_list_url );
- ++iter;
- };
-
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-}
-
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index ffff564ad4..3bb6492a6e 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -44,7 +44,6 @@ class LLRadioGroup;
class LLSlider;
class LLTabContainer;
class LLTextBox;
-class LLMediaCtrl;
class LLTool;
class LLParcelSelection;
class LLObjectSelection;
@@ -98,11 +97,6 @@ public:
static void setEditTool(void* data);
void setTool(const LLSD& user_data);
void saveLastTool();
- void onClickBtnDeleteMedia();
- void onClickBtnAddMedia();
- void onClickBtnEditMedia();
- void clearMediaSettings();
- bool selectedMediaEditable();
void updateLandImpacts();
static void setGridMode(S32 mode);
@@ -111,13 +105,6 @@ public:
private:
void refresh();
- void refreshMedia();
- void getMediaState();
- void updateMediaSettings();
- void navigateToTitleMedia( const std::string url ); // navigate if changed
- void updateMediaTitle();
- static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
- static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
void onClickGridOptions();
@@ -193,19 +180,12 @@ public:
LLParcelSelectionHandle mParcelSelection;
LLObjectSelectionHandle mObjectSelection;
- LLMediaCtrl *mTitleMedia;
- bool mNeedMediaTitle;
-
private:
BOOL mDirty;
BOOL mHasSelection;
std::map<std::string, std::string> mStatusText;
-
-protected:
- LLSD mMediaSettings;
-
public:
static bool sShowObjectCost;
static bool sPreviousFocusOnAvatar;
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index e67c79a3a0..67a205417e 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -1023,7 +1023,7 @@ void LLFloaterUIPreview::onClickEditFloater()
void LLFloaterUIPreview::onClickBrowseForEditor()
{
// Let the user choose an executable through the file picker dialog box
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false);
}
void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filenames)
@@ -1077,7 +1077,7 @@ void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filen
void LLFloaterUIPreview::onClickBrowseForDiffs()
{
// create load dialog box
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterUIPreview::getDiffsFilePath(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index d5c2ad5f81..917d6dfcd0 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -112,16 +112,6 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
- else
- {
- LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
- if(panel_face)
- {
- panel_face->setMediaType(mime_type);
- panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
- }
-
- }
getChildView("loading_label")->setVisible( false);
closeFloater();
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
index 59e1f49f81..23f19dd5aa 100644
--- a/indra/newview/llfloatervoicevolume.cpp
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -127,7 +127,7 @@ void LLFloaterVoiceVolume::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(data);
getChild<LLUICtrl>("avatar_name")->setValue("");
updateVolumeControls();
diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp
deleted file mode 100644
index 891bb90c0e..0000000000
--- a/indra/newview/llfloaterwebprofile.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file llfloaterwebprofile.cpp
- * @brief Avatar profile floater.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterwebprofile.h"
-
-#include "llviewercontrol.h"
-
-LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :
- LLFloaterWebContent(key)
-{
-}
-
-void LLFloaterWebProfile::onOpen(const LLSD& key)
-{
- Params p(key);
- p.show_chrome(true);
- p.window_class("profile");
- p.allow_address_entry(false);
- p.trusted_content(true);
- LLFloaterWebContent::onOpen(p);
- applyPreferredRect();
-}
-
-// virtual
-void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user)
-{
- LL_DEBUGS() << "handleReshape: " << new_rect << LL_ENDL;
-
- if (by_user && !isMinimized())
- {
- LL_DEBUGS() << "Storing new rect" << LL_ENDL;
- gSavedSettings.setRect("WebProfileFloaterRect", new_rect);
- }
-
- LLFloaterWebContent::handleReshape(new_rect, by_user);
-}
-
-LLFloater* LLFloaterWebProfile::create(const LLSD& key)
-{
- LLFloaterWebContent::Params p(key);
- preCreate(p);
- return new LLFloaterWebProfile(p);
-}
-
-void LLFloaterWebProfile::applyPreferredRect()
-{
- const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect");
- LL_DEBUGS() << "Applying preferred rect: " << preferred_rect << LL_ENDL;
-
- // Don't override position that may have been set by floater stacking code.
- LLRect new_rect = getRect();
- new_rect.setLeftTopAndSize(
- new_rect.mLeft, new_rect.mTop,
- preferred_rect.getWidth(), preferred_rect.getHeight());
- setShape(new_rect);
-}
diff --git a/indra/newview/llfloaterwebprofile.h b/indra/newview/llfloaterwebprofile.h
deleted file mode 100644
index 4c355e401b..0000000000
--- a/indra/newview/llfloaterwebprofile.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file llfloaterwebprofile.h
- * @brief Avatar profile floater.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFLOATERWEBPROFILE_H
-#define LL_LLFLOATERWEBPROFILE_H
-
-#include "llfloaterwebcontent.h"
-#include "llviewermediaobserver.h"
-
-#include <string>
-
-class LLMediaCtrl;
-
-/**
- * Displays avatar profile web page.
- */
-class LLFloaterWebProfile
-: public LLFloaterWebContent
-{
- LOG_CLASS(LLFloaterWebProfile);
-public:
- typedef LLFloaterWebContent::Params Params;
-
- LLFloaterWebProfile(const Params& key);
-
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
-
- static LLFloater* create(const LLSD& key);
-
-private:
- void applyPreferredRect();
-};
-
-#endif // LL_LLFLOATERWEBPROFILE_H
-
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 2c84cd1f93..01bfae8934 100644..100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -45,6 +45,7 @@
//#include "llfirstuse.h"
#include "llfloaterreg.h" // getTypedInstance()
#include "llfocusmgr.h"
+#include "lliconctrl.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
@@ -81,7 +82,6 @@
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
-static const F32 MAP_ZOOM_TIME = 0.2f;
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
@@ -284,7 +284,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)
BOOL LLFloaterWorldMap::postBuild()
{
- mPanel = getChild<LLPanel>("objects_mapview");
+ mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview"));
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
avatar_combo->selectFirstItem();
@@ -305,13 +305,13 @@ BOOL LLFloaterWorldMap::postBuild()
landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
- mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f);
- getChild<LLUICtrl>("zoom slider")->setValue(mCurZoomVal);
+ F32 slider_zoom = mMapView->getZoom();
+ getChild<LLUICtrl>("zoom slider")->setValue(slider_zoom);
+
+ getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this));
setDefaultBtn(NULL);
- mZoomTimer.stop();
-
onChangeMaturity();
return TRUE;
@@ -321,7 +321,7 @@ BOOL LLFloaterWorldMap::postBuild()
LLFloaterWorldMap::~LLFloaterWorldMap()
{
// All cleaned up by LLView destructor
- mPanel = NULL;
+ mMapView = NULL;
// Inventory deletes all observers on shutdown
mInventory = NULL;
@@ -359,17 +359,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
mIsClosing = FALSE;
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->clearLastClick();
+ mMapView->clearLastClick();
{
// reset pan on show, so it centers on you again
if (!center_on_target)
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, true);
}
- map_panel->updateVisibleBlocks();
+ mMapView->updateVisibleBlocks();
// Reload items as they may have changed
LLWorldMap::getInstance()->reloadItems();
@@ -417,18 +415,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- if (!isMinimized() && isFrontmost())
- {
- if(mPanel->pointInView(x, y))
- {
- F32 slider_value = (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal();
- slider_value += ((F32)clicks * -0.3333f);
- getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_value));
- return TRUE;
- }
- }
-
- return LLFloater::handleScrollWheel(x, y, clicks);
+ if (!isMinimized() && isFrontmost())
+ {
+ S32 map_x = x - mMapView->getRect().mLeft;
+ S32 map_y = y - mMapView->getRect().mBottom;
+ if (mMapView->pointInView(map_x, map_y))
+ {
+ F32 old_slider_zoom = (F32) getChild<LLUICtrl>("zoom slider")->getValue().asReal();
+ F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f);
+ getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_zoom));
+ mMapView->zoomWithPivot(slider_zoom, map_x, map_y);
+ return true;
+ }
+ }
+
+ return LLFloater::handleScrollWheel(x, y, clicks);
}
@@ -507,26 +508,13 @@ void LLFloaterWorldMap::draw()
setMouseOpaque(TRUE);
getDragHandle()->setMouseOpaque(TRUE);
-
- //RN: snaps to zoom value because interpolation caused jitter in the text rendering
- if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal())
- {
- mZoomTimer.start();
- }
- F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME;
- if (interp > 1.f)
- {
- interp = 1.f;
- mZoomTimer.stop();
- }
- mCurZoomVal = lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp);
- F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
- LLWorldMapView::setScale( map_scale );
+
+ mMapView->zoom((F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal());
// Enable/disable checkboxes depending on the zoom level
// If above threshold level (i.e. low res) -> Disable all checkboxes
// If under threshold level (i.e. high res) -> Enable all checkboxes
- bool enable = LLWorldMapView::showRegionInfo();
+ bool enable = mMapView->showRegionInfo();
getChildView("people_chk")->setEnabled(enable);
getChildView("infohub_chk")->setEnabled(enable);
getChildView("telehub_chk")->setEnabled(enable);
@@ -1005,7 +993,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLCtrlListInterface *list = mListFriendCombo;
- if (list)
+ if (list && list->getSelectedValue().asString() != "None")
{
list->selectByValue( "None" );
}
@@ -1025,9 +1013,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()
S32 world_height_regions = MAX_VISIBLE_REGIONS;
// Find how much space we have to display the world
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)mPanel;
- LLRect view_rect = map_panel->getRect();
+ LLRect view_rect = mMapView->getRect();
// View size in pixels
S32 view_width = view_rect.getWidth();
@@ -1295,9 +1281,9 @@ void LLFloaterWorldMap::onShowTargetBtn()
void LLFloaterWorldMap::onShowAgentBtn()
{
- LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
- // Set flag so user's location will be displayed if not tracking anything else
- mSetToUserPosition = TRUE;
+ mMapView->setPanWithInterpTime(0, 0, false, 0.1f); // false == animate
+ // Set flag so user's location will be displayed if not tracking anything else
+ mSetToUserPosition = true;
}
void LLFloaterWorldMap::onClickTeleportBtn()
@@ -1315,6 +1301,22 @@ void LLFloaterWorldMap::onCopySLURL()
LLNotificationsUtil::add("CopySLURL", args);
}
+void LLFloaterWorldMap::onExpandCollapseBtn()
+{
+ LLLayoutStack* floater_stack = getChild<LLLayoutStack>("floater_map_stack");
+ LLLayoutPanel* controls_panel = getChild<LLLayoutPanel>("controls_lp");
+
+ bool toggle_collapse = !controls_panel->isCollapsed();
+ floater_stack->collapsePanel(controls_panel, toggle_collapse);
+ floater_stack->updateLayout();
+
+ std::string image_name = getString(toggle_collapse ? "expand_icon" : "collapse_icon");
+ std::string tooltip = getString(toggle_collapse ? "expand_tooltip" : "collapse_tooltip");
+ getChild<LLIconCtrl>("expand_collapse_icon")->setImage(LLUI::getUIImage(image_name));
+ getChild<LLIconCtrl>("expand_collapse_icon")->setToolTip(tooltip);
+ getChild<LLPanel>("expand_btn_panel")->setToolTip(tooltip);
+}
+
// protected
void LLFloaterWorldMap::centerOnTarget(BOOL animate)
{
@@ -1349,9 +1351,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
pos_global.clearVec();
}
- LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- !animate);
+ F64 map_scale = (F64)mMapView->getScale();
+ mMapView->setPanWithInterpTime(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)),
+ -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)),
+ !animate, 0.1f);
mWaitingForTracker = FALSE;
}
@@ -1581,7 +1584,7 @@ void LLFloaterWorldMap::onTeleportFinished()
{
if(isInVisibleChain())
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, TRUE);
}
}
@@ -1656,9 +1659,8 @@ void LLFloaterWorldMap::onChangeMaturity()
void LLFloaterWorldMap::onFocusLost()
{
- gViewerWindow->showCursor();
- LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->mPanning = FALSE;
+ gViewerWindow->showCursor();
+ mMapView->mPanning = false;
}
LLPanelHideBeacon::LLPanelHideBeacon() :
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 14a9c26fb9..3702226d23 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -44,6 +44,7 @@ class LLInventoryObserver;
class LLItemInfo;
class LLLineEditor;
class LLTabContainer;
+class LLWorldMapView;
class LLFloaterWorldMap : public LLFloater
{
@@ -130,6 +131,8 @@ protected:
void onShowAgentBtn();
void onCopySLURL();
+ void onExpandCollapseBtn();
+
void centerOnTarget(BOOL animate);
void updateLocation();
@@ -154,11 +157,7 @@ protected:
void onTeleportFinished();
private:
- LLPanel* mPanel; // Panel displaying the map
-
- // Ties to LLWorldMapView::sMapScale, in pixels per region
- F32 mCurZoomVal;
- LLFrameTimer mZoomTimer;
+ LLWorldMapView* mMapView; // Panel displaying the map
// update display of teleport destination coordinates - pos is in global coordinates
void updateTeleportCoordsDisplay( const LLVector3d& pos );
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 0be748ace9..e395da7f1e 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -327,22 +327,63 @@ void LLFriendCardsManager::syncFriendCardsFolders()
/************************************************************************/
/* Private Methods */
/************************************************************************/
-const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
+const LLUUID& LLFriendCardsManager::findFirstCallingCardSubfolder(const LLUUID &parent_id) const
{
- const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+ if (parent_id.isNull())
+ {
+ return LLUUID::null;
+ }
- std::string friendFolderName = get_friend_folder_name();
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(parent_id, cats, items);
- return findChildFolderUUID(callingCardsFolderID, friendFolderName);
+ if (!cats || !items || cats->size() == 0)
+ {
+ // call failed
+ return LLUUID::null;
+ }
+
+ if (cats->size() > 1)
+ {
+ const LLViewerInventoryCategory* friendFolder = gInventory.getCategory(parent_id);
+ if (friendFolder)
+ {
+ LL_WARNS_ONCE() << friendFolder->getName() << " folder contains more than one folder" << LL_ENDL;
+ }
+ }
+
+ for (LLInventoryModel::cat_array_t::const_iterator iter = cats->begin();
+ iter != cats->end();
+ ++iter)
+ {
+ const LLInventoryCategory* category = (*iter);
+ if (category->getPreferredType() == LLFolderType::FT_CALLINGCARD)
+ {
+ return category->getUUID();
+ }
+ }
+
+ return LLUUID::null;
}
-const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+// Inventorry ->
+// Calling Cards - >
+// Friends - > (the only expected folder)
+// All (the only expected folder)
+
+const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
{
- LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
+ const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+ return findFirstCallingCardSubfolder(callingCardsFolderID);
+}
- std::string friendAllSubfolderName = get_friend_all_subfolder_name();
+const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+{
+ LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
- return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName);
+ return findFirstCallingCardSubfolder(friendFolderUUID);
}
const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index 2fb912a930..f5679d7d85 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -116,6 +116,7 @@ private:
}
const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const;
+ const LLUUID& findFirstCallingCardSubfolder(const LLUUID &parent_id) const;
const LLUUID& findFriendFolderUUIDImpl() const;
const LLUUID& findFriendAllSubfolderUUIDImpl() const;
const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID);
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 91ab445273..7c8e8279c2 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -185,7 +185,7 @@ private:
std::set<LLUUID> mLoadingAssets;
// LLEventHost interface
- boost::shared_ptr<LLGestureListener> mListener;
+ std::shared_ptr<LLGestureListener> mListener;
};
#endif
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 175f1849cf..38ec24cae8 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -987,9 +987,8 @@ private:
//-----------------------------------------------------------------------------
F32 gpu_benchmark()
{
- if (!gGLManager.mHasTimerQuery)
+ if (gGLManager.mGLVersion < 3.3f)
{ // don't bother benchmarking venerable drivers which don't support accurate timing anyway
- // and are likely to be correctly identified by the GPU table already.
return -1.f;
}
@@ -1000,8 +999,8 @@ F32 gpu_benchmark()
gBenchmarkProgram.mName = "Benchmark Shader";
gBenchmarkProgram.mFeatures.attachNothing = true;
gBenchmarkProgram.mShaderFiles.clear();
- gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB));
- gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
+ gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
gBenchmarkProgram.mShaderLevel = 1;
if (!gBenchmarkProgram.createShader(NULL, NULL))
{
@@ -1084,7 +1083,7 @@ F32 gpu_benchmark()
delete [] pixels;
//make a dummy triangle to draw with
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW_ARB);
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW);
if (!buff->allocateBuffer(3, 0, true))
{
@@ -1115,16 +1114,6 @@ F32 gpu_benchmark()
// ensure matched pair of bind() and unbind() calls
ShaderBinder binder(gBenchmarkProgram);
-#ifdef GL_ARB_vertex_array_object
- U32 glarray = 0;
-
- if (LLRender::sGLCoreProfile)
- {
- glGenVertexArrays(1, &glarray);
- glBindVertexArray(glarray);
- }
-#endif
-
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
glFinish();
@@ -1157,15 +1146,6 @@ F32 gpu_benchmark()
}
}
-#ifdef GL_ARB_vertex_array_object
- if (LLRender::sGLCoreProfile)
- {
- glBindVertexArray(0);
- glDeleteVertexArrays(1, &glarray);
- }
-#endif
-
-
std::sort(results.begin(), results.end());
F32 gbps = results[results.size()/2];
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
new file mode 100644
index 0000000000..05ed7a2019
--- /dev/null
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -0,0 +1,298 @@
+/**
+ * @file llgltfmateriallist.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llgltfmateriallist.h"
+
+#include "llassetstorage.h"
+#include "lldispatcher.h"
+#include "llfetchedgltfmaterial.h"
+#include "llfilesystem.h"
+#include "llsdserialize.h"
+#include "lltinygltfhelper.h"
+#include "llviewercontrol.h"
+#include "llviewergenericmessage.h"
+#include "llviewerobjectlist.h"
+
+#include "tinygltf/tiny_gltf.h"
+#include <strstream>
+
+#include "json/reader.h"
+#include "json/value.h"
+
+LLGLTFMaterialList gGLTFMaterialList;
+
+namespace
+{
+ class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler
+ {
+ LOG_CLASS(LLGLTFMaterialOverrideDispatchHandler);
+ public:
+ LLGLTFMaterialOverrideDispatchHandler() = default;
+ ~LLGLTFMaterialOverrideDispatchHandler() override = default;
+
+ bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override
+ {
+ // receive override data from simulator via LargeGenericMessage
+ // message should have:
+ // object_id - UUID of LLViewerObject
+ // side - S32 index of texture entry
+ // gltf_json - String of GLTF json for override data
+
+
+ LLSD message;
+
+ sparam_t::const_iterator it = strings.begin();
+ if (it != strings.end()) {
+ const std::string& llsdRaw = *it++;
+ std::istringstream llsdData(llsdRaw);
+ if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))
+ {
+ LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
+ }
+ }
+
+ LLUUID object_id = message["object_id"].asUUID();
+
+ LLViewerObject * obj = gObjectList.findObject(object_id);
+ S32 side = message["side"].asInteger();
+ std::string gltf_json = message["gltf_json"].asString();
+
+ std::string warn_msg, error_msg;
+ LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial();
+ bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg);
+
+ if (!success)
+ {
+ LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL;
+ }
+ else
+ {
+ if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data))
+ {
+ // object not ready to receive override data, queue for later
+ gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data);
+ }
+ }
+
+ return true;
+ }
+ };
+ LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message;
+}
+
+void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data)
+{
+ override_list_t& overrides = mQueuedOverrides[id];
+
+ if (overrides.size() < side + 1)
+ {
+ overrides.resize(side + 1);
+ }
+
+ overrides[side] = override_data;
+}
+
+void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj)
+{
+ const LLUUID& id = obj->getID();
+ auto iter = mQueuedOverrides.find(id);
+
+ if (iter != mQueuedOverrides.end())
+ {
+ override_list_t& overrides = iter->second;
+ for (int i = 0; i < overrides.size(); ++i)
+ {
+ if (overrides[i].notNull())
+ {
+ if (!obj->getTE(i)->getGLTFMaterial())
+ { // object doesn't have its base GLTF material yet, don't apply override (yet)
+ return;
+ }
+ obj->setTEGLTFMaterialOverride(i, overrides[i]);
+ }
+ }
+
+ mQueuedOverrides.erase(iter);
+ }
+}
+
+LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
+{
+ uuid_mat_map_t::iterator iter = mList.find(id);
+ if (iter == mList.end())
+ {
+ LLFetchedGLTFMaterial* mat = new LLFetchedGLTFMaterial();
+ mList[id] = mat;
+
+ if (!mat->mFetching)
+ {
+ // if we do multiple getAssetData calls,
+ // some will get distched, messing ref counter
+ // Todo: get rid of mat->ref()
+ mat->mFetching = true;
+ mat->ref();
+
+ gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL,
+ [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status)
+ {
+ if (status)
+ {
+ LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL;
+ }
+
+ LLFileSystem file(id, asset_type, LLFileSystem::READ);
+ auto size = file.getSize();
+ if (!size)
+ {
+ LL_DEBUGS() << "Zero size material." << LL_ENDL;
+ mat->mFetching = false;
+ mat->unref();
+ return;
+ }
+
+ std::vector<char> buffer;
+ buffer.resize(size);
+ file.read((U8*)&buffer[0], buffer.size());
+
+ LLSD asset;
+
+ // read file into buffer
+ std::istrstream str(&buffer[0], buffer.size());
+
+ if (LLSDSerialize::deserialize(asset, str, buffer.size()))
+ {
+ if (asset.has("version") && asset["version"] == "1.0")
+ {
+ if (asset.has("type") && asset["type"].asString() == "GLTF 2.0")
+ {
+ if (asset.has("data") && asset["data"].isString())
+ {
+ std::string data = asset["data"];
+
+ std::string warn_msg, error_msg;
+
+ if (!mat->fromJSON(data, warn_msg, error_msg))
+ {
+ LL_WARNS() << "Failed to decode material asset: " << LL_ENDL;
+ LL_WARNS() << warn_msg << LL_ENDL;
+ LL_WARNS() << error_msg << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL;
+ }
+
+ mat->mFetching = false;
+ mat->unref();
+ }, nullptr);
+ }
+
+ return mat;
+ }
+
+ return iter->second;
+}
+
+void LLGLTFMaterialList::addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material)
+{
+ mList[id] = material;
+}
+
+void LLGLTFMaterialList::removeMaterial(const LLUUID& id)
+{
+ mList.erase(id);
+}
+
+void LLGLTFMaterialList::flushMaterials()
+{
+ // Similar variant to what textures use
+ static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount"); // default: 32
+ //update MIN_UPDATE_COUNT or 5% of materials, whichever is greater
+ U32 update_count = llmax((U32)MIN_UPDATE_COUNT, (U32)mList.size() / 20);
+ update_count = llmin(update_count, (U32)mList.size());
+
+ const F64 MAX_INACTIVE_TIME = 30.f;
+ F64 cur_time = LLTimer::getTotalSeconds();
+
+ // advance iter one past the last key we updated
+ uuid_mat_map_t::iterator iter = mList.find(mLastUpdateKey);
+ if (iter != mList.end()) {
+ ++iter;
+ }
+
+ while (update_count-- > 0)
+ {
+ if (iter == mList.end())
+ {
+ iter = mList.begin();
+ }
+
+ LLPointer<LLFetchedGLTFMaterial> material = iter->second;
+ if (material->getNumRefs() == 2) // this one plus one from the list
+ {
+
+ if (!material->mActive
+ && cur_time > material->mExpectedFlusTime)
+ {
+ iter = mList.erase(iter);
+ }
+ else
+ {
+ if (material->mActive)
+ {
+ material->mExpectedFlusTime = cur_time + MAX_INACTIVE_TIME;
+ material->mActive = false;
+ }
+ ++iter;
+ }
+ }
+ else
+ {
+ material->mActive = true;
+ ++iter;
+ }
+ }
+
+ if (iter != mList.end())
+ {
+ mLastUpdateKey = iter->first;
+ }
+ else
+ {
+ mLastUpdateKey.setNull();
+ }
+}
+
+// static
+void LLGLTFMaterialList::registerCallbacks()
+{
+ gGenericDispatcher.addHandler("GLTFMaterialOverride", &handle_gltf_override_message);
+}
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
new file mode 100644
index 0000000000..ee32dc8825
--- /dev/null
+++ b/indra/newview/llgltfmateriallist.h
@@ -0,0 +1,70 @@
+/**
+ * @file llgltfmateriallist.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+
+#pragma once
+
+#include "llfetchedgltfmaterial.h"
+#include "llgltfmaterial.h"
+#include "llpointer.h"
+
+#include <unordered_map>
+
+class LLFetchedGLTFMaterial;
+
+class LLGLTFMaterialList
+{
+public:
+ LLGLTFMaterialList() {}
+
+
+ LLGLTFMaterial* getMaterial(const LLUUID& id);
+
+ void addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material);
+ void removeMaterial(const LLUUID& id);
+
+ void flushMaterials();
+
+ static void registerCallbacks();
+
+ // save an override update for later (for example, if an override arrived for an unknown object)
+ void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data);
+
+ void applyQueuedOverrides(LLViewerObject* obj);
+
+private:
+ typedef std::unordered_map<LLUUID, LLPointer<LLFetchedGLTFMaterial > > uuid_mat_map_t;
+ uuid_mat_map_t mList;
+
+ typedef std::vector<LLPointer<LLGLTFMaterial> > override_list_t;
+ typedef std::unordered_map<LLUUID, override_list_t > queued_override_map_t;
+ queued_override_map_t mQueuedOverrides;
+
+ LLUUID mLastUpdateKey;
+};
+
+extern LLGLTFMaterialList gGLTFMaterialList;
+
+
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index e7bc2a9268..84a1278767 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -196,7 +196,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
// static
void LLGroupActions::search()
{
- LLFloaterReg::showInstance("search");
+ LLFloaterReg::showInstance("search", LLSD().with("collection", "groups"));
}
// static
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 62414d3bbb..32af2592d3 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -45,7 +45,6 @@
#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
-S32 LLGroupListItem::sIconWidth = 0;
class LLGroupComparator : public LLFlatListView::ItemComparator
{
@@ -65,21 +64,81 @@ public:
}
};
-static const LLGroupComparator GROUP_COMPARATOR;
+class LLSharedGroupComparator : public LLFlatListView::ItemComparator
+{
+public:
+ LLSharedGroupComparator() {};
+
+ /*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ const LLGroupListItem* group_item1 = static_cast<const LLGroupListItem*>(item1);
+ std::string name1 = group_item1->getGroupName();
+ bool item1_shared = gAgent.isInGroup(group_item1->getGroupID(), true);
+
+ const LLGroupListItem* group_item2 = static_cast<const LLGroupListItem*>(item2);
+ std::string name2 = group_item2->getGroupName();
+ bool item2_shared = gAgent.isInGroup(group_item2->getGroupID(), true);
+ if (item2_shared != item1_shared)
+ {
+ return item1_shared;
+ }
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
+ }
+};
+
+static LLGroupComparator GROUP_COMPARATOR;
+static LLSharedGroupComparator SHARED_GROUP_COMPARATOR;
+
+LLGroupList::Params::Params()
+: for_agent("for_agent", true)
+{
+}
LLGroupList::LLGroupList(const Params& p)
: LLFlatListViewEx(p)
+ , mForAgent(p.for_agent)
, mDirty(true) // to force initial update
+ , mShowIcons(false)
+ , mShowNone(true)
{
- // Listen for agent group changes.
- gAgent.addListener(this, "new group");
-
- mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
setCommitOnSelectionChange(true);
// Set default sort order.
- setComparator(&GROUP_COMPARATOR);
+ if (mForAgent)
+ {
+ setComparator(&GROUP_COMPARATOR);
+ }
+ else
+ {
+ // shared groups first
+ setComparator(&SHARED_GROUP_COMPARATOR);
+ }
+
+ if (mForAgent)
+ {
+ enableForAgent(true);
+ }
+}
+
+LLGroupList::~LLGroupList()
+{
+ if (mForAgent) gAgent.removeListener(this);
+ if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
+}
+
+void LLGroupList::enableForAgent(bool show_icons)
+{
+ mForAgent = true;
+
+ mShowIcons = mForAgent && gSavedSettings.getBOOL("GroupListShowIcons") && show_icons;
+
+ // Listen for agent group changes.
+ gAgent.addListener(this, "new group");
// Set up context menu.
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -94,12 +153,6 @@ LLGroupList::LLGroupList(const Params& p)
mContextMenuHandle = context_menu->getHandle();
}
-LLGroupList::~LLGroupList()
-{
- gAgent.removeListener(this);
- if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
-}
-
// virtual
void LLGroupList::draw()
{
@@ -114,12 +167,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- LLToggleableMenu* context_menu = mContextMenuHandle.get();
- if (context_menu && size() > 0)
- {
- context_menu->buildDrawLabels();
- context_menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, context_menu, x, y);
+ if (mForAgent)
+ {
+ LLToggleableMenu* context_menu = mContextMenuHandle.get();
+ if (context_menu && size() > 0)
+ {
+ context_menu->buildDrawLabels();
+ context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, context_menu, x, y);
+ }
}
return handled;
@@ -132,7 +188,7 @@ BOOL LLGroupList::handleDoubleClick(S32 x, S32 y, MASK mask)
// Handle double click only for the selected item in the list, skip clicks on empty space.
if (handled)
{
- if (mDoubleClickSignal)
+ if (mDoubleClickSignal && getItemsRect().pointInRect(x, y))
{
(*mDoubleClickSignal)(this, x, y, mask);
}
@@ -164,34 +220,49 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
void LLGroupList::refresh()
{
- const LLUUID& highlight_id = gAgent.getGroupID();
- S32 count = gAgent.mGroups.size();
- LLUUID id;
- bool have_filter = !mNameFilter.empty();
-
- clear();
-
- for(S32 i = 0; i < count; ++i)
- {
- id = gAgent.mGroups.at(i).mID;
- const LLGroupData& group_data = gAgent.mGroups.at(i);
- if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
- continue;
- addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
- }
-
- // Sort the list.
- sort();
-
- // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
- // but only if some real groups exists. EXT-4838
- if (!have_filter && count > 0)
- {
- std::string loc_none = LLTrans::getString("GroupsNone");
- addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
- }
-
- selectItemByUUID(highlight_id);
+ if (mForAgent)
+ {
+ const LLUUID& highlight_id = gAgent.getGroupID();
+ S32 count = gAgent.mGroups.size();
+ LLUUID id;
+ bool have_filter = !mNameFilter.empty();
+
+ clear();
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ id = gAgent.mGroups.at(i).mID;
+ const LLGroupData& group_data = gAgent.mGroups.at(i);
+ if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
+ continue;
+ addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM, group_data.mListInProfile);
+ }
+
+ // Sort the list.
+ sort();
+
+ // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
+ // but only if some real groups exists. EXT-4838
+ if (!have_filter && count > 0 && mShowNone)
+ {
+ std::string loc_none = LLTrans::getString("GroupsNone");
+ addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
+ }
+
+ selectItemByUUID(highlight_id);
+ }
+ else
+ {
+ clear();
+
+ for (group_map_t::iterator it = mGroups.begin(); it != mGroups.end(); ++it)
+ {
+ addNewItem(it->second, it->first, LLUUID::null, ADD_BOTTOM);
+ }
+
+ // Sort the list.
+ sort();
+ }
setDirty(false);
onCommit();
@@ -212,13 +283,19 @@ void LLGroupList::toggleIcons()
}
}
+void LLGroupList::setGroups(const std::map< std::string,LLUUID> group_list)
+{
+ mGroups = group_list;
+ setDirty(true);
+}
+
//////////////////////////////////////////////////////////////////////////
// PRIVATE Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos)
+void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos, bool visible_in_profile)
{
- LLGroupListItem* item = new LLGroupListItem();
+ LLGroupListItem* item = new LLGroupListItem(mForAgent, mShowIcons);
item->setGroupID(id);
item->setName(name, mNameFilter);
@@ -227,7 +304,10 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
item->getChildView("info_btn")->setVisible( false);
item->getChildView("profile_btn")->setVisible( false);
item->setGroupIconVisible(mShowIcons);
-
+ if (!mShowIcons)
+ {
+ item->setVisibleInProfile(visible_in_profile);
+ }
addItem(item, id, pos);
// setCommentVisible(false);
@@ -243,6 +323,29 @@ bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD&
return true;
}
+ if (event->desc() == "value_changed")
+ {
+ LLSD data = event->getValue();
+ if (data.has("group_id") && data.has("visible"))
+ {
+ LLUUID group_id = data["group_id"].asUUID();
+ bool visible = data["visible"].asBoolean();
+
+ std::vector<LLPanel*> items;
+ getItems(items);
+ for (std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
+ {
+ LLGroupListItem* item = dynamic_cast<LLGroupListItem*>(*it);
+ if (item && item->getGroupID() == group_id)
+ {
+ item->setVisibleInProfile(visible);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
return false;
}
@@ -294,21 +397,25 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
/* LLGroupListItem implementation */
/************************************************************************/
-LLGroupListItem::LLGroupListItem()
+LLGroupListItem::LLGroupListItem(bool for_agent, bool show_icons)
: LLPanel(),
mGroupIcon(NULL),
mGroupNameBox(NULL),
mInfoBtn(NULL),
-mGroupID(LLUUID::null)
+mProfileBtn(NULL),
+mVisibilityHideBtn(NULL),
+mVisibilityShowBtn(NULL),
+mGroupID(LLUUID::null),
+mForAgent(for_agent)
{
- buildFromFile( "panel_group_list_item.xml");
-
- // Remember group icon width including its padding from the name text box,
- // so that we can hide and show the icon again later.
- if (!sIconWidth)
- {
- sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
- }
+ if (show_icons)
+ {
+ buildFromFile( "panel_group_list_item.xml");
+ }
+ else
+ {
+ buildFromFile( "panel_group_list_item_short.xml");
+ }
}
LLGroupListItem::~LLGroupListItem()
@@ -325,7 +432,25 @@ BOOL LLGroupListItem::postBuild()
mInfoBtn = getChild<LLButton>("info_btn");
mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this));
- childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this));
+ mProfileBtn = getChild<LLButton>("profile_btn");
+ mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); });
+
+ mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn");
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(false); });
+ }
+ mVisibilityShowBtn = findChild<LLButton>("visibility_show_btn");
+ if (mVisibilityShowBtn)
+ {
+ mVisibilityShowBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(true); });
+ }
+
+ // Remember group icon width including its padding from the name text box,
+ // so that we can hide and show the icon again later.
+ // Also note that panel_group_list_item and panel_group_list_item_short
+ // have icons of different sizes so we need to figure it per file.
+ mIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
return TRUE;
}
@@ -344,7 +469,16 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
if (mGroupID.notNull()) // don't show the info button for the "none" group
{
mInfoBtn->setVisible(true);
- getChildView("profile_btn")->setVisible( true);
+ mProfileBtn->setVisible(true);
+ if (mForAgent && mVisibilityHideBtn)
+ {
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile);
+ mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile);
+ }
+ }
}
LLPanel::onMouseEnter(x, y, mask);
@@ -354,7 +488,12 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
getChildView("hovered_icon")->setVisible( false);
mInfoBtn->setVisible(false);
- getChildView("profile_btn")->setVisible( false);
+ mProfileBtn->setVisible(false);
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setVisible(false);
+ mVisibilityShowBtn->setVisible(false);
+ }
LLPanel::onMouseLeave(x, y, mask);
}
@@ -372,7 +511,17 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id)
mID = group_id;
mGroupID = group_id;
- setActive(group_id == gAgent.getGroupID());
+
+ if (mForAgent)
+ {
+ // Active group should be bold.
+ setBold(group_id == gAgent.getGroupID());
+ }
+ else
+ {
+ // Groups shared with the agent should be bold
+ setBold(gAgent.isInGroup(group_id, true));
+ }
LLGroupMgr::getInstance()->addObserver(this);
}
@@ -393,24 +542,28 @@ void LLGroupListItem::setGroupIconVisible(bool visible)
// Move the group name horizontally by icon size + its distance from the group name.
LLRect name_rect = mGroupNameBox->getRect();
- name_rect.mLeft += visible ? sIconWidth : -sIconWidth;
+ name_rect.mLeft += visible ? mIconWidth : -mIconWidth;
mGroupNameBox->setRect(name_rect);
}
+void LLGroupListItem::setVisibleInProfile(bool visible)
+{
+ mGroupNameBox->setColor(LLUIColorTable::instance().getColor((visible ? "GroupVisibleInProfile" : "GroupHiddenInProfile"), LLColor4::red).get());
+}
+
//////////////////////////////////////////////////////////////////////////
// Private Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupListItem::setActive(bool active)
+void LLGroupListItem::setBold(bool bold)
{
// *BUG: setName() overrides the style params.
- // Active group should be bold.
LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
// *NOTE dzaporozhan
// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font
// is predefined as bold (SansSerifSmallBold, for example)
- new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
+ new_desc.setStyle(bold ? LLFontGL::BOLD : LLFontGL::NORMAL);
LLFontGL* new_font = LLFontGL::getFont(new_desc);
mGroupNameStyle.font = new_font;
@@ -430,11 +583,25 @@ void LLGroupListItem::onProfileBtnClick()
LLGroupActions::show(mGroupID);
}
+void LLGroupListItem::onVisibilityBtnClick(bool new_visibility)
+{
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ gAgent.setUserGroupFlags(mGroupID, agent_gdatap.mAcceptNotices, new_visibility);
+ setVisibleInProfile(new_visibility);
+ mVisibilityHideBtn->setVisible(new_visibility);
+ mVisibilityShowBtn->setVisible(!new_visibility);
+ }
+}
+
void LLGroupListItem::changed(LLGroupChange gc)
{
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
- if(group_data)
- setGroupIconID(group_data->mInsigniaID);
+ if ((gc == GC_ALL || gc == GC_PROPERTIES) && group_data)
+ {
+ setGroupIconID(group_data->mInsigniaID);
+ }
}
//EOF
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 171b77fb00..5cbabb712f 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -50,12 +50,15 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
public:
struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
{
- Params(){};
+ Optional<bool> for_agent;
+ Params();
};
LLGroupList(const Params& p);
virtual ~LLGroupList();
+ void enableForAgent(bool show_icons);
+
virtual void draw(); // from LLView
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); // from LLView
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); // from LLView
@@ -63,13 +66,16 @@ public:
void setNameFilter(const std::string& filter);
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
+ void setIconsVisible(bool show_icons) { mShowIcons = show_icons; }
+ void setShowNone(bool show_none) { mShowNone = show_none; }
+ void setGroups(const std::map< std::string,LLUUID> group_list);
LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
private:
void setDirty(bool val = true) { mDirty = val; }
void refresh();
- void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM);
+ void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM, bool visible_in_profile = true);
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
bool onContextMenuItemClick(const LLSD& userdata);
@@ -80,6 +86,11 @@ private:
bool mShowIcons;
bool mDirty;
std::string mNameFilter;
+
+ bool mForAgent;
+ bool mShowNone;
+ typedef std::map< std::string,LLUUID> group_map_t;
+ group_map_t mGroups;
};
class LLButton;
@@ -90,7 +101,7 @@ class LLGroupListItem : public LLPanel
, public LLGroupMgrObserver
{
public:
- LLGroupListItem();
+ LLGroupListItem(bool for_agent, bool show_icons);
~LLGroupListItem();
/*virtual*/ BOOL postBuild();
/*virtual*/ void setValue(const LLSD& value);
@@ -106,19 +117,26 @@ public:
void setGroupIconVisible(bool visible);
virtual void changed(LLGroupChange gc);
+
+ void setVisibleInProfile(bool visible);
private:
- void setActive(bool active);
+ void setBold(bool bold);
void onInfoBtnClick();
void onProfileBtnClick();
+ void onVisibilityBtnClick(bool new_visibility);
LLTextBox* mGroupNameBox;
LLUUID mGroupID;
LLGroupIconCtrl* mGroupIcon;
- LLButton* mInfoBtn;
+ LLButton* mInfoBtn;
+ LLButton* mProfileBtn;
+ LLButton* mVisibilityHideBtn;
+ LLButton* mVisibilityShowBtn;
std::string mGroupName;
+ bool mForAgent;
LLStyle::Params mGroupNameStyle;
- static S32 sIconWidth; // icon width + padding
+ S32 mIconWidth;
};
#endif // LL_LLGROUPLIST_H
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 7f65153879..a9e5e55451 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -53,6 +53,7 @@
#include "llviewerregion.h"
#include <boost/regex.hpp>
#include "llcorehttputil.h"
+#include "lluiusage.h"
#if LL_MSVC
@@ -1859,6 +1860,9 @@ void LLGroupMgr::sendGroupRoleMemberChanges(const LLUUID& group_id)
//static
void LLGroupMgr::sendGroupMemberJoin(const LLUUID& group_id)
{
+
+ LLUIUsage::instance().logCommand("Group.Join");
+
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_JoinGroupRequest);
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 6898dce7b1..0f230067bc 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -495,7 +495,7 @@ void LLHUDEffectLookAt::render()
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
gGL.matrixMode(LLRender::MM_MODELVIEW);
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index ecf6d42d69..dfa299528a 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -322,7 +322,7 @@ void LLHUDEffectPointAt::render()
update();
if (sDebugPointAt && mTargetType != POINTAT_TARGET_NONE)
{
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLVector3 target = mTargetPos + mSourceObject->getRenderPosition();
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 85a878c4a2..38be2b69fd 100644
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -64,7 +64,6 @@ LLHUDIcon::icon_instance_t LLHUDIcon::sIconInstances;
LLHUDIcon::LLHUDIcon(const U8 type) :
LLHUDObject(type),
mImagep(NULL),
- mPickID(0),
mScale(0.1f),
mHidden(FALSE)
{
@@ -76,15 +75,11 @@ LLHUDIcon::~LLHUDIcon()
mImagep = NULL;
}
-void LLHUDIcon::renderIcon(BOOL for_select)
+void LLHUDIcon::render()
{
LLGLSUIDefault texture_state;
LLGLDepthTest gls_depth(GL_TRUE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
- if (for_select)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
if (mHidden)
return;
@@ -116,7 +111,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
mDistance = dist_vec(icon_position, camera->getOrigin());
- F32 alpha_factor = for_select ? 1.f : clamp_rescale(mDistance, DIST_START_FADE, DIST_END_FADE, 1.f, 0.f);
+ F32 alpha_factor = clamp_rescale(mDistance, DIST_START_FADE, DIST_END_FADE, 1.f, 0.f);
LLVector3 x_pixel_vec;
LLVector3 y_pixel_vec;
@@ -150,13 +145,6 @@ void LLHUDIcon::renderIcon(BOOL for_select)
LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale;
LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale;
- if (for_select)
- {
- // set color to unique color id for picking
- LLColor4U coloru((U8)(mPickID >> 16), (U8)(mPickID >> 8), (U8)mPickID);
- gGL.color4ubv(coloru.mV);
- }
- else
{
LLColor4 icon_color = LLColor4::white;
icon_color.mV[VALPHA] = alpha_factor;
@@ -198,11 +186,6 @@ void LLHUDIcon::markDead()
LLHUDObject::markDead();
}
-void LLHUDIcon::render()
-{
- renderIcon(FALSE);
-}
-
BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
if (mHidden)
@@ -296,37 +279,6 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
}
//static
-S32 LLHUDIcon::generatePickIDs(S32 start_id, S32 step_size)
-{
- S32 cur_id = start_id;
- icon_instance_t::iterator icon_it;
-
- for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
- {
- (*icon_it)->mPickID = cur_id;
- cur_id += step_size;
- }
-
- return cur_id;
-}
-
-//static
-LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)
-{
- icon_instance_t::iterator icon_it;
-
- for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
- {
- if (pick_id == (*icon_it)->mPickID)
- {
- return *icon_it;
- }
- }
-
- return NULL;
-}
-
-//static
LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
icon_instance_t::iterator icon_it;
diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h
index e00a985ddc..7f452b5c36 100644
--- a/indra/newview/llhudicon.h
+++ b/indra/newview/llhudicon.h
@@ -56,8 +56,6 @@ public:
void restartLifeTimer() { mLifeTimer.reset(); }
- static S32 generatePickIDs(S32 start_id, S32 step_size);
- static LLHUDIcon* handlePick(S32 pick_id);
static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
static void updateAll();
@@ -75,14 +73,11 @@ protected:
LLHUDIcon(const U8 type);
~LLHUDIcon();
- void renderIcon(BOOL for_select); // common render code
-
private:
LLPointer<LLViewerTexture> mImagep;
LLFrameTimer mAnimTimer;
LLFrameTimer mLifeTimer;
F32 mDistance;
- S32 mPickID;
F32 mScale;
BOOL mHidden;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 952fbf8e4b..e2d63ecc0a 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -228,7 +228,7 @@ void LLHUDNameTag::render()
if (sDisplayText)
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderText(FALSE);
}
}
diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 45fa09e1a1..fe6793ce73 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -267,6 +267,13 @@ void LLHUDObject::updateAll()
// static
void LLHUDObject::renderAll()
{
+ LLGLSUIDefault gls_ui;
+
+ gGL.color4f(1, 1, 1, 1);
+
+ gUIProgram.bind();
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
LLHUDObject *hud_objp;
hud_object_list_t::iterator object_it;
@@ -285,6 +292,7 @@ void LLHUDObject::renderAll()
}
LLVertexBuffer::unbind();
+ gUIProgram.unbind();
}
// static
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 7be35ac260..7511dabd5b 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -102,7 +102,7 @@ void LLHUDText::render()
if (!mOnHUDAttachment && sDisplayText)
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderText();
}
}
@@ -330,7 +330,7 @@ void LLHUDText::updateVisibility()
if (!mSourceObject)
{
- LL_WARNS() << "HUD text: mSourceObject is NULL, mOnHUDAttachment: " << mOnHUDAttachment << LL_ENDL;
+ // Beacons
mVisible = TRUE;
if (mOnHUDAttachment)
{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b7e0a6a794..4d6ebf9cbb 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -69,7 +69,7 @@
#include "message.h"
#include "llviewerregion.h"
#include "llcorehttputil.h"
-
+#include "lluiusage.h"
const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -532,7 +532,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
mSessionInitialized(false),
mCallBackEnabled(true),
mTextIMPossible(true),
- mOtherParticipantIsAvatar(true),
mStartCallOnInitialize(false),
mStartedAsIMCall(voice),
mIsDNDsend(false),
@@ -544,13 +543,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType)
{
mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
- mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID);
-
- // check if it was AVALINE call
- if (!mOtherParticipantIsAvatar)
- {
- mSessionType = AVALINE_SESSION;
- }
}
else
{
@@ -651,9 +643,6 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
switch(mSessionType)
{
- case AVALINE_SESSION:
- // no text notifications
- break;
case P2P_SESSION:
LLAvatarNameCache::get(mOtherParticipantID, &av_name);
other_avatar_name = av_name.getUserName();
@@ -781,6 +770,23 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f
message["index"] = (LLSD::Integer)mMsgs.size();
message["is_history"] = is_history;
+ LL_DEBUGS("UIUsage") << "addMessage " << " from " << from << " from_id " << from_id << " utf8_text " << utf8_text << " time " << time << " is_history " << is_history << " session mType " << mType << LL_ENDL;
+ if (from_id == gAgent.getID())
+ {
+ if (mType == IM_SESSION_GROUP_START)
+ {
+ LLUIUsage::instance().logCommand("Chat.SendGroup");
+ }
+ else if (mType == IM_NOTHING_SPECIAL)
+ {
+ LLUIUsage::instance().logCommand("Chat.SendIM");
+ }
+ else
+ {
+ LLUIUsage::instance().logCommand("Chat.SendOther");
+ }
+ }
+
mMsgs.push_front(message);
if (mSpeakers && from_id.notNull())
@@ -913,11 +919,6 @@ bool LLIMModel::LLIMSession::isGroupChat()
return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID, TRUE));
}
-bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
-{
- return !mOtherParticipantIsAvatar;
-}
-
LLUUID LLIMModel::LLIMSession::generateOutgoingAdHocHash() const
{
LLUUID hash = LLUUID::null;
@@ -1795,7 +1796,6 @@ LLIMMgr::onConfirmForceCloseError(
LLCallDialogManager::LLCallDialogManager():
mPreviousSessionlName(""),
-mPreviousSessionType(LLIMModel::LLIMSession::P2P_SESSION),
mCurrentSessionlName(""),
mSession(NULL),
mOldState(LLVoiceChannel::STATE_READY)
@@ -1826,12 +1826,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution
return;
}
-
- if (mSession)
- {
- // store previous session type to process Avaline calls in dialogs
- mPreviousSessionType = mSession->mSessionType;
- }
mSession = session;
@@ -1857,7 +1851,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
- mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = LLVoiceChannel::STATE_CALL_STARTED;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@@ -1893,7 +1886,6 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
- mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = new_state;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@@ -1910,8 +1902,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
break;
case LLVoiceChannel::STATE_HUNG_UP:
- // this state is coming before session is changed, so, put it into payload map
- mCallDialogPayload["old_session_type"] = mSession->mSessionType;
+ // this state is coming before session is changed
break;
case LLVoiceChannel::STATE_CONNECTED :
@@ -2031,7 +2022,6 @@ void LLCallDialog::onOpen(const LLSD& key)
void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
{
- // *NOTE: 12/28/2009: check avaline calls: LLVoiceClient::isParticipantAvatar returns false for them
bool participant_is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
bool is_group = participant_is_avatar && gAgent.isInGroup(session_id, TRUE);
@@ -2052,8 +2042,8 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
}
else
{
- avatar_icon->setValue("Avaline_Icon");
- avatar_icon->setToolTip(std::string(""));
+ LL_WARNS() << "Participant neither avatar nor group" << LL_ENDL;
+ group_icon->setValue(session_id);
}
}
@@ -2097,13 +2087,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
// tell the user which voice channel they are leaving
if (!mPayload["old_channel_name"].asString().empty())
{
- bool was_avaline_call = LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["old_session_type"].asInteger();
-
std::string old_caller_name = mPayload["old_channel_name"].asString();
- if (was_avaline_call)
- {
- old_caller_name = LLTextUtil::formatPhoneNumber(old_caller_name);
- }
getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", old_caller_name);
show_oldchannel = true;
@@ -2116,10 +2100,6 @@ void LLOutgoingCallDialog::show(const LLSD& key)
if (!mPayload["disconnected_channel_name"].asString().empty())
{
std::string channel_name = mPayload["disconnected_channel_name"].asString();
- if (LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["session_type"].asInteger())
- {
- channel_name = LLTextUtil::formatPhoneNumber(channel_name);
- }
getChild<LLUICtrl>("nearby")->setTextArg("[VOICE_CHANNEL_NAME]", channel_name);
// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice,
@@ -2135,16 +2115,11 @@ void LLOutgoingCallDialog::show(const LLSD& key)
std::string callee_name = mPayload["session_name"].asString();
LLUUID session_id = mPayload["session_id"].asUUID();
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- if (callee_name == "anonymous")
+ if (callee_name == "anonymous") // obsolete? Likely was part of avaline support
{
callee_name = getString("anonymous");
}
- else if (!is_avatar)
- {
- callee_name = LLTextUtil::formatPhoneNumber(callee_name);
- }
LLSD callee_id = mPayload["other_user_id"];
// Beautification: Since you know who you called, just show display name
@@ -2344,18 +2319,11 @@ BOOL LLIncomingCallDialog::postBuild()
call_type = getString(notify_box_type);
}
- // check to see if this is an Avaline call
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- if (caller_name == "anonymous")
+ if (caller_name == "anonymous") // obsolete? Likely was part of avaline support
{
caller_name = getString("anonymous");
setCallerName(caller_name, caller_name, call_type);
}
- else if (!is_avatar)
- {
- caller_name = LLTextUtil::formatPhoneNumber(caller_name);
- setCallerName(caller_name, caller_name, call_type);
- }
else
{
// Get the full name information
@@ -2375,7 +2343,7 @@ BOOL LLIncomingCallDialog::postBuild()
if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc")
{
- // starting notification's timer for P2P and AVALINE invitations
+ // starting notification's timer for P2P invitations
mLifetimeTimer.start();
}
else
@@ -2384,7 +2352,7 @@ BOOL LLIncomingCallDialog::postBuild()
}
//it's not possible to connect to existing Ad-Hoc/Group chat through incoming ad-hoc call
- //and no IM for avaline
+ bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup");
setCanDrag(FALSE);
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 79c831ebb6..fdf9806e2e 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -72,7 +72,6 @@ public:
P2P_SESSION,
GROUP_SESSION,
ADHOC_SESSION,
- AVALINE_SESSION,
NONE_SESSION,
} SType;
@@ -92,12 +91,10 @@ public:
bool isAdHoc();
bool isP2P();
bool isGroupChat();
- bool isOtherParticipantAvaline();
bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}
bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;}
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
- bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
LLUUID generateOutgoingAdHocHash() const;
@@ -136,7 +133,6 @@ public:
bool mCallBackEnabled;
bool mTextIMPossible;
- bool mOtherParticipantIsAvatar;
bool mStartCallOnInitialize;
//if IM session is created for a voice call
@@ -516,7 +512,6 @@ private:
protected:
std::string mPreviousSessionlName;
- LLIMModel::LLIMSession::SType mPreviousSessionType;
std::string mCurrentSessionlName;
LLIMModel::LLIMSession* mSession;
LLVoiceChannel::EState mOldState;
diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp
index 479e8f9abf..f382b5985f 100644
--- a/indra/newview/llinspect.cpp
+++ b/indra/newview/llinspect.cpp
@@ -147,3 +147,19 @@ bool LLInspect::childHasVisiblePopupMenu()
}
return false;
}
+
+void LLInspect::repositionInspector(const LLSD& data)
+{
+ // Position the inspector relative to the mouse cursor
+ // Similar to how tooltips are positioned
+ // See LLToolTipMgr::createToolTip
+ if (data.has("pos"))
+ {
+ LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
+ }
+ else
+ {
+ LLUI::getInstance()->positionViewNearMouse(this);
+ }
+ applyRectControl();
+}
diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h
index 1f6aafc7bd..6909aa3f16 100644
--- a/indra/newview/llinspect.h
+++ b/indra/newview/llinspect.h
@@ -49,6 +49,8 @@ public:
/// Inspectors close themselves when they lose focus
/*virtual*/ void onFocusLost();
+
+ void repositionInspector(const LLSD& data);
protected:
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 10814ac076..b11c440015 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -45,7 +45,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "lltextbox.h"
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
class LLFetchAvatarData;
@@ -202,17 +201,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// Generate link to avatar profile.
LLTextBase* avatar_profile_link = getChild<LLTextBase>("avatar_profile_link");
@@ -348,7 +337,7 @@ void LLInspectAvatar::onClickMuteVolume()
LLMuteList* mute_list = LLMuteList::getInstance();
bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
- LLMute mute(mAvatarID, mAvatarName.getDisplayName(), LLMute::AGENT);
+ LLMute mute(mAvatarID, mAvatarName.getUserName(), LLMute::AGENT);
if (!is_muted)
{
mute_list->add(mute, LLMute::flagVoiceChat);
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index fa8a53c546..0a30ab9217 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -38,7 +38,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "llresmgr.h" // getMonetaryString()
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
#include "lluictrl.h"
#include "llgroupiconctrl.h"
@@ -124,17 +123,7 @@ void LLInspectGroup::onOpen(const LLSD& data)
setGroupID(data["group_id"]);
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// can't call from constructor as widgets are not built yet
requestUpdate();
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index f78a5cc64e..3d13985f08 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -28,16 +28,17 @@
#include "llinspectobject.h"
// Viewer
+#include "llagent.h" // To standup
#include "llfloatersidepanelcontainer.h"
#include "llinspect.h"
#include "llmediaentry.h"
-#include "llnotificationsutil.h" // *TODO: Eliminate, add LLNotificationsUtil wrapper
#include "llselectmgr.h"
#include "llslurl.h"
#include "llviewermenu.h" // handle_object_touch(), handle_buy()
#include "llviewermedia.h"
#include "llviewermediafocus.h"
#include "llviewerobjectlist.h" // to select the requested object
+#include "llvoavatarself.h"
// Linden libraries
#include "llbutton.h" // setLabel(), not virtual!
@@ -49,7 +50,6 @@
#include "lltextbox.h" // for description truncation
#include "lltoggleablemenu.h"
#include "lltrans.h"
-#include "llui.h" // positionViewNearMouse()
#include "lluictrl.h"
class LLViewerObject;
@@ -116,6 +116,7 @@ private:
viewer_media_t mMediaImpl;
LLMediaEntry* mMediaEntry;
LLSafeHandle<LLObjectSelection> mObjectSelection;
+ boost::signals2::connection mSelectionUpdateSlot;
};
LLInspectObject::LLInspectObject(const LLSD& sd)
@@ -141,6 +142,10 @@ LLInspectObject::LLInspectObject(const LLSD& sd)
LLInspectObject::~LLInspectObject()
{
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
}
/*virtual*/
@@ -175,9 +180,12 @@ BOOL LLInspectObject::postBuild(void)
getChild<LLUICtrl>("more_info_btn")->setCommitCallback(
boost::bind(&LLInspectObject::onClickMoreInfo, this));
- // Watch for updates to selection properties off the network
- LLSelectMgr::getInstance()->mUpdateSignal.connect(
- boost::bind(&LLInspectObject::update, this) );
+ if (!mSelectionUpdateSlot.connected())
+ {
+ // Watch for updates to selection properties off the network
+ mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(
+ boost::bind(&LLInspectObject::update, this));
+ }
return TRUE;
}
@@ -197,17 +205,8 @@ void LLInspectObject::onOpen(const LLSD& data)
{
mObjectFace = data["object_face"];
}
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+
+ LLInspect::repositionInspector(data);
// Promote hovered object to a complete selection, which will also force
// a request for selected object data off the network
@@ -635,7 +634,31 @@ void LLInspectObject::onClickTouch()
void LLInspectObject::onClickSit()
{
- handle_object_sit_or_stand();
+ bool is_sitting = false;
+ if (mObjectSelection)
+ {
+ LLSelectNode* node = mObjectSelection->getFirstRootNode();
+ if (node && node->mValid)
+ {
+ LLViewerObject* root_object = node->getObject();
+ if (root_object
+ && isAgentAvatarValid()
+ && gAgentAvatarp->isSitting()
+ && gAgentAvatarp->getRoot() == root_object)
+ {
+ is_sitting = true;
+ }
+ }
+ }
+
+ if (is_sitting)
+ {
+ gAgent.standUp();
+ }
+ else
+ {
+ handle_object_sit(mObjectID);
+ }
closeFloater();
}
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
index 272c8acbd5..77320510a6 100644
--- a/indra/newview/llinspectremoteobject.cpp
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -111,17 +111,7 @@ void LLInspectRemoteObject::onOpen(const LLSD& data)
// update the inspector with the current object state
update();
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
}
void LLInspectRemoteObject::onClickMap()
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index d0034eff13..68801b0895 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -110,7 +110,7 @@ void LLInspectToast::onOpen(const LLSD& notification_id)
panel_rect = panel->getRect();
reshape(panel_rect.getWidth(), panel_rect.getHeight());
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(notification_id);
}
// virtual
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a0de3a2af1..f7789853b8 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -785,13 +785,29 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if (obj)
{
- items.push_back(std::string("Copy Separator"));
+ if (obj->getType() != LLAssetType::AT_CATEGORY)
+ {
+ items.push_back(std::string("Copy Separator"));
+ }
items.push_back(std::string("Copy"));
if (!isItemCopyable())
{
disabled_items.push_back(std::string("Copy"));
}
+ if (isAgentInventory())
+ {
+ items.push_back(std::string("New folder from selected"));
+ items.push_back(std::string("Subfolder Separator"));
+ std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs();
+ uuid_vec_t ids;
+ std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
+ if (!is_only_items_selected(ids) && !is_only_cats_selected(ids))
+ {
+ disabled_items.push_back(std::string("New folder from selected"));
+ }
+ }
+
if (obj->getIsLinkType())
{
items.push_back(std::string("Find Original"));
@@ -878,7 +894,10 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
}
- items.push_back(std::string("Paste Separator"));
+ if (obj->getType() != LLAssetType::AT_CATEGORY)
+ {
+ items.push_back(std::string("Paste Separator"));
+ }
addDeleteContextMenuOptions(items, disabled_items);
@@ -1102,7 +1121,10 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
LLInventoryModel::cat_array_t categories;
LLInventoryModel::item_array_t items;
gInventory.collectDescendents(local_version_folder_id, categories, items, FALSE);
- if (categories.size() >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount"))
+ LLCachedControl<U32> max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4);
+ LLCachedControl<U32> max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20);
+ if (categories.size() >= max_count
+ || depth > (max_depth + 1))
{
disabled_items.push_back(std::string("New Folder"));
}
@@ -1420,6 +1442,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
new_listener = new LLSettingsBridge(inventory, root, uuid, LLSettingsType::fromInventoryFlags(flags));
break;
+ case LLAssetType::AT_MATERIAL:
+ if (inv_type != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL;
+ }
+ new_listener = new LLMaterialBridge(inventory, root, uuid);
+ break;
+
default:
LL_INFOS_ONCE() << "Unhandled asset type (llassetstorage.h): "
<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL;
@@ -3798,7 +3828,20 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
if (item && can_move_to_landmarks(item))
{
- dropToFavorites(item);
+ if (LLClipboard::instance().isCutMode())
+ {
+ LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
+ llassert(viitem);
+ if (viitem)
+ {
+ //changeItemParent() implicity calls dirtyFilter
+ changeItemParent(model, viitem, parent_id, FALSE);
+ }
+ }
+ else
+ {
+ dropToFavorites(item);
+ }
}
}
else if (LLClipboard::instance().isCutMode())
@@ -4011,6 +4054,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Note"));
disabled_items.push_back(std::string("New Settings"));
disabled_items.push_back(std::string("New Gesture"));
+ disabled_items.push_back(std::string("New Material"));
disabled_items.push_back(std::string("New Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
@@ -4038,6 +4082,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Script"));
disabled_items.push_back(std::string("New Note"));
disabled_items.push_back(std::string("New Gesture"));
+ disabled_items.push_back(std::string("New Material"));
disabled_items.push_back(std::string("New Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
@@ -4092,20 +4137,25 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
if (!isInboxFolder() // don't allow creation in inbox
&& outfits_id != mUUID)
{
+ bool menu_items_added = false;
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
{
items.push_back(std::string("New Folder"));
+ menu_items_added = true;
}
if (!isMarketplaceListingsFolder())
{
items.push_back(std::string("New Script"));
items.push_back(std::string("New Note"));
items.push_back(std::string("New Gesture"));
+ items.push_back(std::string("New Material"));
items.push_back(std::string("New Clothes"));
items.push_back(std::string("New Body Parts"));
items.push_back(std::string("New Settings"));
items.push_back(std::string("upload_def"));
+
+ menu_items_added = true;
if (!LLEnvironment::instance().isInventoryEnabled())
{
@@ -4113,6 +4163,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
}
+ if (menu_items_added)
+ {
+ items.push_back(std::string("Create Separator"));
+ }
}
getClipboardEntries(false, items, disabled_items, flags);
}
@@ -4266,7 +4320,16 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
items.push_back(std::string("Conference Chat Folder"));
items.push_back(std::string("IM All Contacts In Folder"));
}
+
+ if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren())
+ {
+ items.push_back(std::string("Ungroup folder items"));
+ }
}
+ else
+ {
+ disabled_items.push_back(std::string("New folder from selected"));
+ }
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
@@ -4378,6 +4441,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
break;
case DAD_LINK:
@@ -6007,6 +6071,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
const LLPermissions& perm = inv_item->getPermissions();
@@ -7198,6 +7263,39 @@ bool LLSettingsBridge::canUpdateRegion() const
// +=================================================+
+// | LLMaterialBridge |
+// +=================================================+
+
+void LLMaterialBridge::openItem()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+}
+
+void LLMaterialBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ LL_DEBUGS() << "LLMaterialBridge::buildContextMenu()" << LL_ENDL;
+
+ if (isMarketplaceListingsFolder())
+ {
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ hide_context_entries(menu, items, disabled_items);
+ }
+ else
+ {
+ LLItemBridge::buildContextMenu(menu, flags);
+ }
+}
+
+
+// +=================================================+
// | LLLinkBridge |
// +=================================================+
// For broken folder links.
@@ -7584,6 +7682,24 @@ protected:
LLSettingsBridgeAction(const LLUUID& id, LLInventoryModel* model) : LLInvFVBridgeAction(id, model) {}
};
+class LLMaterialBridgeAction : public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ void doIt() override
+ {
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("material_editor", LLSD(item->getUUID()), TAKE_FOCUS_YES);
+ }
+ LLInvFVBridgeAction::doIt();
+ }
+ ~LLMaterialBridgeAction() = default;
+private:
+ LLMaterialBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {}
+};
+
LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type,
const LLUUID& uuid,
@@ -7626,6 +7742,9 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
case LLAssetType::AT_SETTINGS:
action = new LLSettingsBridgeAction(uuid, model);
break;
+ case LLAssetType::AT_MATERIAL:
+ action = new LLMaterialBridgeAction(uuid, model);
+ break;
default:
break;
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 0b0ef273e1..6c1ddd716b 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -637,6 +637,17 @@ protected:
};
+class LLMaterialBridge : public LLItemBridge
+{
+public:
+ LLMaterialBridge(LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid) :
+ LLItemBridge(inventory, root, uuid) {}
+ virtual void openItem();
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInvFVBridgeAction
//
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 707ff2b7b6..f7dc493109 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -1306,6 +1306,18 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
+ if (isFilterObjectTypesWith(LLInventoryType::IT_MATERIAL))
+ {
+ filtered_types += LLTrans::getString("Materials");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ not_filtered_types += LLTrans::getString("Materials");
+ filtered_by_all_types = FALSE;
+ }
+
if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
{
filtered_types += LLTrans::getString("Notecards");
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index d239b23e83..27edc8148e 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1868,6 +1868,86 @@ void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
}
}
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLInventoryItem* inv_item = gInventory.getItem(*it);
+ if (inv_item)
+ {
+ change_item_parent(*it, new_cat_uuid);
+ }
+ else
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (inv_cat && !LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
+ {
+ gInventory.changeCategoryParent((LLViewerInventoryCategory*)inv_cat, new_cat_uuid, false);
+ }
+ }
+ }
+
+ LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
+ if (!floater_inventory)
+ {
+ LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
+ return;
+ }
+ LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ if (sidepanel_inventory)
+ {
+ if (sidepanel_inventory->getActivePanel())
+ {
+ sidepanel_inventory->getActivePanel()->setSelection(new_cat_uuid, TAKE_FOCUS_YES);
+ LLFolderViewItem* fv_folder = sidepanel_inventory->getActivePanel()->getItemByID(new_cat_uuid);
+ if (fv_folder)
+ {
+ fv_folder->setOpen(TRUE);
+ }
+ }
+ }
+}
+
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (!inv_cat)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool is_only_items_selected(const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
+ if (!inv_item)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name)
+{
+ LLInventoryObject* first_item = gInventory.getObject(*selected_uuids.begin());
+ if (!first_item)
+ {
+ return;
+ }
+
+ inventory_func_type func = boost::bind(&move_items_to_folder, _1, selected_uuids);
+ gInventory.createNewCategory(first_item->getParentUUID(), LLFolderType::FT_NONE, folder_name, func);
+
+}
+
///----------------------------------------------------------------------------
/// LLInventoryCollectFunctor implementations
///----------------------------------------------------------------------------
@@ -2522,6 +2602,81 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
{
(new LLDirPickerThread(boost::bind(&LLInventoryAction::saveMultipleTextures, _1, selected_items, model), std::string()))->getFile();
}
+ else if ("new_folder_from_selected" == action)
+ {
+
+ LLInventoryObject* first_item = gInventory.getObject(*ids.begin());
+ if (!first_item)
+ {
+ return;
+ }
+ const LLUUID& parent_uuid = first_item->getParentUUID();
+ for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLInventoryObject *item = gInventory.getObject(*it);
+ if (!item || item->getParentUUID() != parent_uuid)
+ {
+ LLNotificationsUtil::add("SameFolderRequired");
+ return;
+ }
+ }
+
+ LLSD args;
+ args["DESC"] = LLTrans::getString("New Folder");
+
+ LLNotificationsUtil::add("CreateSubfolder", args, LLSD(),
+ [ids](const LLSD& notification, const LLSD& response)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (opt == 0)
+ {
+ std::string settings_name = response["message"].asString();
+
+ LLInventoryObject::correctInventoryName(settings_name);
+ if (settings_name.empty())
+ {
+ settings_name = LLTrans::getString("New Folder");
+ }
+ move_items_to_new_subfolder(ids, settings_name);
+ }
+ });
+ }
+ else if ("ungroup_folder_items" == action)
+ {
+ if (selected_uuid_set.size() == 1)
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin());
+ if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
+ {
+ return;
+ }
+ const LLUUID &new_cat_uuid = inv_cat->getParentUUID();
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cat_array, item_array);
+ LLInventoryModel::cat_array_t cats = *cat_array;
+ LLInventoryModel::item_array_t items = *item_array;
+
+ for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin(); cat_iter != cats.end(); ++cat_iter)
+ {
+ LLViewerInventoryCategory* cat = *cat_iter;
+ if (cat)
+ {
+ gInventory.changeCategoryParent(cat, new_cat_uuid, false);
+ }
+ }
+ for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); item_iter != items.end(); ++item_iter)
+ {
+ LLViewerInventoryItem* item = *item_iter;
+ if(item)
+ {
+ gInventory.changeItemParent(item, new_cat_uuid, false);
+ }
+ }
+ gInventory.removeCategory(inv_cat->getUUID());
+ gInventory.notifyObservers();
+ }
+ }
else
{
std::set<LLFolderViewItem*>::iterator set_iter;
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 8915bfa1e0..ba9f157e47 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -93,6 +93,10 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id);
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name);
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids);
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids);
+bool is_only_items_selected(const uuid_vec_t& selected_uuids);
/** Miscellaneous global functions
** **
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 44e493fdf4..e9b0e8404a 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -99,6 +99,8 @@ LLIconDictionary::LLIconDictionary()
addEntry(LLInventoryType::ICONNAME_SETTINGS_DAY, new IconEntry("Inv_SettingsDay"));
addEntry(LLInventoryType::ICONNAME_SETTINGS, new IconEntry("Inv_Settings"));
+ addEntry(LLInventoryType::ICONNAME_MATERIAL, new IconEntry("Inv_Material"));
+
addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("Inv_Invalid"));
addEntry(LLInventoryType::ICONNAME_UNKNOWN, new IconEntry("Inv_Unknown"));
@@ -177,6 +179,9 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
case LLAssetType::AT_SETTINGS:
idx = assignSettingsIcon(misc_flag);
break;
+ case LLAssetType::AT_MATERIAL:
+ idx = LLInventoryType::ICONNAME_MATERIAL;
+ break;
case LLAssetType::AT_UNKNOWN:
idx = LLInventoryType::ICONNAME_UNKNOWN;
default:
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 12bb609df8..de6a850b57 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -298,31 +298,41 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem
applyXUILayout(icon_params, this);
mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
- if (mIconCtrl)
- {
- addChild(mIconCtrl);
- }
- else
+ if (!mIconCtrl)
{
LLIconCtrl::Params icon_params;
icon_params.name = "item_icon";
mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
}
+ if (mIconCtrl)
+ {
+ addChild(mIconCtrl);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create mIconCtrl" << LL_ENDL;
+ }
+
LLTextBox::Params text_params(params.item_name);
applyXUILayout(text_params, this);
mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params);
- if (mTitleCtrl)
+ if (!mTitleCtrl)
{
- addChild(mTitleCtrl);
- }
- else
- {
- LLTextBox::Params text_aprams;
+ LLTextBox::Params text_params;
text_params.name = "item_title";
mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params);
}
+
+ if (mTitleCtrl)
+ {
+ addChild(mTitleCtrl);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create mTitleCtrl" << LL_ENDL;
+ }
}
class WidgetVisibilityChanger
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index c101033a5d..b5853ad9a3 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -135,15 +135,7 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
///----------------------------------------------------------------------------
/// Class LLInventoryValidationInfo
///----------------------------------------------------------------------------
-LLInventoryValidationInfo::LLInventoryValidationInfo():
- mFatalErrorCount(0),
- mWarningCount(0),
- mLoopCount(0),
- mOrphanedCount(0),
- mInitialized(false),
- mFatalNoRootFolder(false),
- mFatalNoLibraryRootFolder(false),
- mFatalQADebugMode(false)
+LLInventoryValidationInfo::LLInventoryValidationInfo()
{
}
@@ -165,7 +157,6 @@ std::ostream& operator<<(std::ostream& os, const LLInventoryValidationInfo& v)
void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
{
sd["fatal_error_count"] = mFatalErrorCount;
- sd["warning_count"] = mWarningCount;
sd["loop_count"] = mLoopCount;
sd["orphaned_count"] = mOrphanedCount;
sd["initialized"] = mInitialized;
@@ -173,6 +164,20 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
sd["fatal_no_root_folder"] = mFatalNoRootFolder;
sd["fatal_no_library_root_folder"] = mFatalNoLibraryRootFolder;
sd["fatal_qa_debug_mode"] = mFatalQADebugMode;
+
+ sd["warning_count"] = mWarningCount;
+ if (mWarningCount>0)
+ {
+ sd["warnings"] = LLSD::emptyArray();
+ for (auto const& it : mWarnings)
+ {
+ S32 val =LLSD::Integer(it.second);
+ if (val>0)
+ {
+ sd["warnings"][it.first] = val;
+ }
+ }
+ }
if (mMissingRequiredSystemFolders.size()>0)
{
sd["missing_system_folders"] = LLSD::emptyArray();
@@ -342,13 +347,13 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL
return NULL;
}
-LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
+LLInventoryModel::EAncestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
{
LLInventoryObject *object = getObject(object_id);
if (!object)
{
LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL;
- return ANSCESTOR_MISSING;
+ return ANCESTOR_MISSING;
}
std::set<LLUUID> object_ids{ object_id }; // loop protection
@@ -358,19 +363,19 @@ LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(co
if (object_ids.find(parent_id) != object_ids.end())
{
LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL;
- return ANSCESTOR_LOOP;
+ return ANCESTOR_LOOP;
}
object_ids.insert(parent_id);
LLInventoryObject *parent_object = getObject(parent_id);
if (!parent_object)
{
LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL;
- return ANSCESTOR_MISSING;
+ return ANCESTOR_MISSING;
}
object = parent_object;
}
result = object->getUUID();
- return ANSCESTOR_OK;
+ return ANCESTOR_OK;
}
// Get the object by id. Returns NULL if not found.
@@ -539,9 +544,18 @@ void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::E
LLViewerInventoryCategory* cat = getCategory(*it);
changeCategoryParent(cat, main_id, TRUE);
}
-
+
// Purge the emptied folder
- removeCategory(folder_id);
+ // Note that this might be a system folder, don't validate removability
+ LLViewerInventoryCategory* cat = getCategory(folder_id);
+ if (cat)
+ {
+ const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (trash_id.notNull())
+ {
+ changeCategoryParent(cat, trash_id, TRUE);
+ }
+ }
remove_inventory_category(folder_id, NULL);
}
}
@@ -628,6 +642,11 @@ const LLUUID LLInventoryModel::findUserDefinedCategoryUUIDForType(LLFolderType::
cat_id = LLUUID(gSavedPerAccountSettings.getString("AnimationUploadFolder"));
break;
}
+ case LLFolderType::FT_MATERIAL:
+ {
+ cat_id = LLUUID(gSavedPerAccountSettings.getString("PBRUploadFolder"));
+ break;
+ }
default:
break;
}
@@ -2822,6 +2841,7 @@ void LLInventoryModel::createCommonSystemCategories()
gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, true);
gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, true); // folder should exist before user tries to 'landmark this'
gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS, true);
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL, true); // probably should be server created
gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, true);
}
@@ -3129,7 +3149,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
gInventory.accountForUpdate(update);
}
- U32 changes = 0x0;
if (account)
{
mask |= LLInventoryObserver::CREATE;
@@ -3137,7 +3156,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
//as above, this loop never seems to loop more than once per call
for (item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
- changes |= gInventory.updateItem(*it, mask);
+ gInventory.updateItem(*it, mask);
}
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
@@ -3896,9 +3915,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo;
S32 fatal_errs = 0;
- S32 warnings = 0;
- S32 loops = 0;
- S32 orphaned = 0;
+ S32 warning_count= 0;
+ S32 loop_count = 0;
+ S32 orphaned_count = 0;
if (getRootFolderID().isNull())
{
@@ -3919,7 +3938,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// ParentChild should be one larger because of the special entry for null uuid.
LL_INFOS("Inventory") << "unexpected sizes: cat map size " << mCategoryMap.size()
<< " parent/child " << mParentChildCategoryTree.size() << LL_ENDL;
- warnings++;
+
+ validation_info->mWarnings["category_map_size"]++;
+ warning_count++;
}
S32 cat_lock = 0;
S32 item_lock = 0;
@@ -3938,32 +3959,35 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cat)
{
LL_WARNS("Inventory") << "null cat" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_cat"]++;
+ warning_count++;
continue;
}
LLUUID topmost_ancestor_id;
// Will leave as null uuid on failure
- EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
+ EAncestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
switch (res)
{
- case ANSCESTOR_MISSING:
- orphaned++;
+ case ANCESTOR_MISSING:
+ orphaned_count++;
break;
- case ANSCESTOR_LOOP:
- loops++;
+ case ANCESTOR_LOOP:
+ loop_count++;
break;
- case ANSCESTOR_OK:
+ case ANCESTOR_OK:
break;
default:
LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["unknown_ancestor_status"]++;
+ warning_count++;
break;
}
if (cat_id != cat->getUUID())
{
LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["cat_id_index_mismatch"]++;
+ warning_count++;
}
if (cat->getParentUUID().isNull())
@@ -3973,7 +3997,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "cat " << cat_id << " has no parent, but is not root ("
<< getRootFolderID() << ") or library root ("
<< getLibraryRootFolderID() << ")" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_parent"]++;
+ warning_count++;
}
}
cat_array_t* cats;
@@ -3982,7 +4007,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cats || !items)
{
LL_WARNS("Inventory") << "invalid direct descendents for " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["direct_descendents"]++;
+ warning_count++;
continue;
}
if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
@@ -4000,7 +4026,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " cached " << cat->getDescendentCount()
<< " expected " << cats->size() << "+" << items->size()
<< "=" << cats->size() +items->size() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["invalid_descendent_count"]++;
+ warning_count++;
}
}
if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
@@ -4024,7 +4051,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!item)
{
LL_WARNS("Inventory") << "null item at index " << i << " for cat " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_item_at_index"]++;
+ warning_count++;
continue;
}
@@ -4035,7 +4063,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "wrong parent for " << item_id << " found "
<< item->getParentUUID() << " expected " << cat_id
<< LL_ENDL;
- warnings++;
+ validation_info->mWarnings["wrong_parent_for_item"]++;
+ warning_count++;
}
@@ -4045,7 +4074,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " found as child of "
<< cat_id << " but not in top level mItemMap" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["item_not_in_top_map"]++;
+ warning_count++;
}
else
{
@@ -4059,11 +4089,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// Topmost ancestor should be root or library.
LLUUID topmost_ancestor_id;
- EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
- if (found != ANSCESTOR_OK)
+ EAncestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
+ if (found != ANCESTOR_OK)
{
LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_found"]++;
+ warning_count++;
}
else
{
@@ -4074,7 +4105,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " got " << topmost_ancestor_id
<< " expected " << getRootFolderID()
<< " or " << getLibraryRootFolderID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_recognized"]++;
+ warning_count++;
}
}
}
@@ -4090,7 +4122,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4108,7 +4140,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
}
}
@@ -4117,7 +4149,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LLFolderType::EType folder_type = cat->getPreferredType();
bool cat_is_in_library = false;
LLUUID topmost_id;
- if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID())
+ if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANCESTOR_OK && topmost_id == getLibraryRootFolderID())
{
cat_is_in_library = true;
}
@@ -4150,14 +4182,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (item->getUUID() != item_id)
{
LL_WARNS("Inventory") << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["item_id_mismatch"]++;
+ warning_count++;
}
const LLUUID& parent_id = item->getParentUUID();
if (parent_id.isNull())
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4168,7 +4201,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4185,7 +4218,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
}
@@ -4203,18 +4236,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType()
<< " missing backlink info at target_id " << target_id
<< LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
// Links should have referents.
if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
{
LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
{
LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
if (target_item && target_item->getIsLinkType())
{
@@ -4286,23 +4319,30 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (is_automatic)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL;
- fatal_errs++;
validation_info->mMissingRequiredSystemFolders.insert(folder_type);
+ fatal_errs++;
}
else
{
// Can create, and will when needed.
- warnings++;
+ // (Not sure this is really a warning, but worth logging)
+ validation_info->mWarnings["missing_system_folder_can_create"]++;
+ warning_count++;
}
}
else if (count_under_root > 1)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL;
validation_info->mDuplicateRequiredSystemFolders.insert(folder_type);
- if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS)
+ if (!is_automatic
+ && folder_type != LLFolderType::FT_SETTINGS
+ // FT_MATERIAL might need to be automatic like the rest of upload folders
+ && folder_type != LLFolderType::FT_MATERIAL
+ )
{
// It is a fatal problem or can lead to fatal problems for COF,
// outfits, trash and other non-automatic folders.
+ validation_info->mFatalSystemDuplicate++;
fatal_errs++;
}
else
@@ -4310,13 +4350,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// For automatic folders it's not a fatal issue and shouldn't
// break inventory or other functionality further
// Exception: FT_SETTINGS is not automatic, but only deserves a warning.
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++;
+ warning_count++;
}
}
if (count_elsewhere > 0)
{
LL_WARNS("Inventory") << "Found " << count_elsewhere << " extra folders of type " << ft << " outside of root" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++;
+ warning_count++;
}
}
}
@@ -4338,12 +4380,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// FIXME need to fail login and tell user to retry, contact support if problem persists.
bool valid = (fatal_errs == 0);
- LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
+ LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warning_count << ", valid: " << valid << LL_ENDL;
validation_info->mFatalErrorCount = fatal_errs;
- validation_info->mWarningCount = warnings;
- validation_info->mLoopCount = loops;
- validation_info->mOrphanedCount = orphaned;
+ validation_info->mWarningCount = warning_count;
+ validation_info->mLoopCount = loop_count;
+ validation_info->mOrphanedCount = orphaned_count;
return validation_info;
}
@@ -4548,12 +4590,10 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore:
}
// as above, this loop never seems to loop more than once per call
- U32 changes(0U);
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
- changes |= gInventory.updateItem(*it);
+ gInventory.updateItem(*it);
}
- // *HUH: Have computed 'changes', nothing uses it.
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 85343cf95c..cb960d8185 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -65,15 +65,19 @@ public:
void toOstream(std::ostream& os) const;
void asLLSD(LLSD& sd) const;
+ bool mInitialized{false};
+ S32 mWarningCount{0};
+ std::map<std::string,U32> mWarnings;
+
+ S32 mLoopCount{0}; // Presence of folders whose ancestors loop onto themselves
+ S32 mOrphanedCount{0}; // Missing or orphaned items, links and folders
+
+ S32 mFatalErrorCount{0};
+ bool mFatalNoRootFolder{false};
+ S32 mFatalSystemDuplicate{0};
+ bool mFatalNoLibraryRootFolder{false};
+ bool mFatalQADebugMode{false};
- S32 mFatalErrorCount;
- S32 mWarningCount;
- S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves
- S32 mOrphanedCount; // Missing or orphaned items, links and folders
- bool mInitialized;
- bool mFatalNoRootFolder;
- bool mFatalNoLibraryRootFolder;
- bool mFatalQADebugMode;
std::set<LLFolderType::EType> mMissingRequiredSystemFolders;
std::set<LLFolderType::EType> mDuplicateRequiredSystemFolders;
};
@@ -286,13 +290,13 @@ public:
// Check if one object has a parent chain up to the category specified by UUID.
BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const;
- enum EAnscestorResult{
- ANSCESTOR_OK = 0,
- ANSCESTOR_MISSING = 1,
- ANSCESTOR_LOOP = 2,
+ enum EAncestorResult{
+ ANCESTOR_OK = 0,
+ ANCESTOR_MISSING = 1,
+ ANCESTOR_LOOP = 2,
};
// Follow parent chain to the top.
- EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
+ EAncestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
//--------------------------------------------------------------------
// Find
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 6b102c7500..bc035fc2f6 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1612,6 +1612,10 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
{
gSavedPerAccountSettings.setString("AnimationUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString());
}
+ else if (param == "pbr_material")
+ {
+ gSavedPerAccountSettings.setString("PBRUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString());
+ }
}
void LLInventoryPanel::purgeSelectedItems()
@@ -2010,7 +2014,43 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
void LLAssetFilteredInventoryPanel::initFromParams(const Params& p)
{
- mAssetType = LLAssetType::lookup(p.filter_asset_type.getValue());
+ // Init asset types
+ std::string types = p.filter_asset_types.getValue();
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("|");
+ tokenizer tokens(types, sep);
+ tokenizer::iterator token_iter = tokens.begin();
+
+ memset(mAssetTypes, 0, LLAssetType::AT_COUNT * sizeof(bool));
+ while (token_iter != tokens.end())
+ {
+ const std::string& token_str = *token_iter;
+ LLAssetType::EType asset_type = LLAssetType::lookup(token_str);
+ if (asset_type > LLAssetType::AT_NONE && asset_type < LLAssetType::AT_COUNT)
+ {
+ mAssetTypes[asset_type] = true;
+ }
+ ++token_iter;
+ }
+
+ // Init drag types
+ memset(mDragTypes, 0, EDragAndDropType::DAD_COUNT * sizeof(bool));
+ for (S32 i = 0; i < LLAssetType::AT_COUNT; i++)
+ {
+ if (mAssetTypes[i])
+ {
+ EDragAndDropType drag_type = LLViewerAssetType::lookupDragAndDropType((LLAssetType::EType)i);
+ if (drag_type != DAD_NONE)
+ {
+ mDragTypes[drag_type] = true;
+ }
+ }
+ }
+ // Always show AT_CATEGORY, but it shouldn't get into mDragTypes
+ mAssetTypes[LLAssetType::AT_CATEGORY] = true;
+
+ // Init the panel
LLInventoryPanel::initFromParams(p);
U64 filter_cats = getFilter().getFilterCategoryTypes();
filter_cats &= ~(1ULL << LLFolderType::FT_MARKETPLACE_LISTINGS);
@@ -2028,10 +2068,9 @@ BOOL LLAssetFilteredInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, B
if (mAcceptsDragAndDrop)
{
- EDragAndDropType allow_type = LLViewerAssetType::lookupDragAndDropType(mAssetType);
// Don't allow DAD_CATEGORY here since it can contain other items besides required assets
// We should see everything we drop!
- if (allow_type == cargo_type)
+ if (mDragTypes[cargo_type])
{
result = LLInventoryPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
@@ -2047,8 +2086,14 @@ bool LLAssetFilteredInventoryPanel::typedViewsFilter(const LLUUID& id, LLInvento
{
return false;
}
+ LLAssetType::EType asset_type = objectp->getType();
+
+ if (asset_type < 0 || asset_type >= LLAssetType::AT_COUNT)
+ {
+ return false;
+ }
- if (objectp->getType() != mAssetType && objectp->getType() != LLAssetType::AT_CATEGORY)
+ if (!mAssetTypes[asset_type])
{
return false;
}
@@ -2064,11 +2109,16 @@ void LLAssetFilteredInventoryPanel::itemChanged(const LLUUID& id, U32 mask, cons
return;
}
- if (model_item
- && model_item->getType() != mAssetType
- && model_item->getType() != LLAssetType::AT_CATEGORY)
+ if (model_item)
{
- return;
+ LLAssetType::EType asset_type = model_item->getType();
+
+ if (asset_type < 0
+ || asset_type >= LLAssetType::AT_COUNT
+ || !mAssetTypes[asset_type])
+ {
+ return;
+ }
}
LLInventoryPanel::itemChanged(id, mask, model_item);
@@ -2104,6 +2154,7 @@ namespace LLInitParam
declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX);
declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT);
declare(LLFolderType::lookup(LLFolderType::FT_SETTINGS) , LLFolderType::FT_SETTINGS);
+ declare(LLFolderType::lookup(LLFolderType::FT_MATERIAL) , LLFolderType::FT_MATERIAL);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_LISTINGS) , LLFolderType::FT_MARKETPLACE_LISTINGS);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_STOCK), LLFolderType::FT_MARKETPLACE_STOCK);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_VERSION), LLFolderType::FT_MARKETPLACE_VERSION);
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 552c61b915..d5219a22e7 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -393,9 +393,9 @@ public:
struct Params
: public LLInitParam::Block<Params, LLInventoryPanel::Params>
{
- Mandatory<std::string> filter_asset_type;
+ Mandatory<std::string> filter_asset_types;
- Params() : filter_asset_type("filter_asset_type") {}
+ Params() : filter_asset_types("filter_asset_types") {}
};
void initFromParams(const Params& p);
@@ -416,7 +416,8 @@ protected:
/*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
private:
- LLAssetType::EType mAssetType;
+ bool mAssetTypes[LLAssetType::AT_COUNT];
+ bool mDragTypes[EDragAndDropType::DAD_COUNT];
};
#endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
index 1364067949..ce4ec668f1 100644
--- a/indra/newview/lllegacyatmospherics.cpp
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -386,7 +386,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
return;
}
- const BOOL hide_clip_plane = TRUE;
LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f);
const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
@@ -472,33 +471,17 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
render_fog_color = sky_fog_color;
- F32 fog_density = 0.f;
fog_distance = mFogRatio * distance;
if (camera_height > water_height)
{
LLColor4 fog(render_fog_color);
mGLFogCol = fog;
-
- if (hide_clip_plane)
- {
- // For now, set the density to extend to the cull distance.
- const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
- fog_density = f_log/fog_distance;
- }
- else
- {
- const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
- fog_density = (f_log)/fog_distance;
- }
}
else
{
LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
F32 depth = water_height - camera_height;
-
- // get the water param manager variables
- float water_fog_density = pwater->getModifiedWaterFogDensity(depth <= 0.0f);
LLColor4 water_fog_color(pwater->getWaterFogColor());
@@ -512,9 +495,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
// set the gl fog color
mGLFogCol = fogCol;
-
- // set the density based on what the shaders use
- fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
}
mFogColor = sky_fog_color;
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 5a17332fde..257208470e 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -47,7 +47,6 @@
/* misc headers */
#include "llscrolllistctrl.h"
-#include "llfilepicker.h"
#include "lllocaltextureobject.h"
#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
@@ -62,6 +61,7 @@
#include "pipeline.h"
#include "llmaterialmgr.h"
#include "llimagedimensionsinfo.h"
+#include "llinventoryicon.h"
#include "llviewercontrol.h"
#include "lltrans.h"
#include "llviewerdisplay.h"
@@ -919,51 +919,49 @@ LLLocalBitmapMgr::~LLLocalBitmapMgr()
mBitmapList.clear();
}
-bool LLLocalBitmapMgr::addUnit()
+bool LLLocalBitmapMgr::addUnit(const std::vector<std::string>& filenames)
{
- bool add_successful = false;
-
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE))
- {
- mTimer.stopTimer();
+ bool add_successful = false;
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty() && addUnit(*iter).notNull())
+ {
+ add_successful = true;
+ }
+ iter++;
+ }
+ return add_successful;
+}
- std::string filename = picker.getFirstFile();
- while(!filename.empty())
- {
- if(!checkTextureDimensions(filename))
- {
- filename = picker.getNextFile();
- continue;
- }
+LLUUID LLLocalBitmapMgr::addUnit(const std::string& filename)
+{
+ if (!checkTextureDimensions(filename))
+ {
+ return LLUUID::null;
+ }
- LLLocalBitmap* unit = new LLLocalBitmap(filename);
+ LLLocalBitmap* unit = new LLLocalBitmap(filename);
- if (unit->getValid())
- {
- mBitmapList.push_back(unit);
- add_successful = true;
- }
- else
- {
- LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
- << "Filename: " << filename << LL_ENDL;
-
- LLSD notif_args;
- notif_args["FNAME"] = filename;
- LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
+ if (unit->getValid())
+ {
+ mBitmapList.push_back(unit);
+ return unit->getTrackingID();
+ }
+ else
+ {
+ LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
+ << "Filename: " << filename << LL_ENDL;
- delete unit;
- unit = NULL;
- }
+ LLSD notif_args;
+ notif_args["FNAME"] = filename;
+ LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
- filename = picker.getNextFile();
- }
-
- mTimer.startTimer();
- }
+ delete unit;
+ unit = NULL;
+ }
- return add_successful;
+ return LLUUID::null;
}
bool LLLocalBitmapMgr::checkTextureDimensions(std::string filename)
@@ -1071,7 +1069,9 @@ void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)
{
if (ctrl)
{
- ctrl->clearRows();
+ std::string icon_name = LLInventoryIcon::getIconName(
+ LLAssetType::AT_TEXTURE,
+ LLInventoryType::IT_NONE);
if (!mBitmapList.empty())
{
@@ -1079,13 +1079,19 @@ void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)
iter != mBitmapList.end(); iter++)
{
LLSD element;
- element["columns"][0]["column"] = "unit_name";
- element["columns"][0]["type"] = "text";
- element["columns"][0]["value"] = (*iter)->getShortName();
- element["columns"][1]["column"] = "unit_id_HIDDEN";
- element["columns"][1]["type"] = "text";
- element["columns"][1]["value"] = (*iter)->getTrackingID();
+ element["columns"][0]["column"] = "icon";
+ element["columns"][0]["type"] = "icon";
+ element["columns"][0]["value"] = icon_name;
+
+ element["columns"][1]["column"] = "unit_name";
+ element["columns"][1]["type"] = "text";
+ element["columns"][1]["value"] = (*iter)->getShortName();
+
+ LLSD data;
+ data["id"] = (*iter)->getTrackingID();
+ data["type"] = (S32)LLAssetType::AT_TEXTURE;
+ element["value"] = data;
ctrl->addElement(element);
}
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index d5ee7efdc6..bb026ed3aa 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -115,14 +115,15 @@ class LLLocalBitmapMgr : public LLSingleton<LLLocalBitmapMgr>
LLSINGLETON(LLLocalBitmapMgr);
~LLLocalBitmapMgr();
public:
- bool addUnit();
+ bool addUnit(const std::vector<std::string>& filenames);
+ LLUUID addUnit(const std::string& filename);
void delUnit(LLUUID tracking_id);
bool checkTextureDimensions(std::string filename);
LLUUID getWorldID(LLUUID tracking_id);
bool isLocal(LLUUID world_id);
std::string getFilename(LLUUID tracking_id);
-
+
void feedScrollList(LLScrollListCtrl* ctrl);
void doUpdates();
void setNeedsRebake();
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp
new file mode 100644
index 0000000000..f194226fa5
--- /dev/null
+++ b/indra/newview/lllocalgltfmaterials.cpp
@@ -0,0 +1,628 @@
+/**
+ * @file lllocalrendermaterials.cpp
+ * @brief Local GLTF materials source
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/* precompiled headers */
+#include "llviewerprecompiledheaders.h"
+
+/* own header */
+#include "lllocalgltfmaterials.h"
+
+/* boost: will not compile unless equivalent is undef'd, beware. */
+#include "fix_macros.h"
+#include <boost/filesystem.hpp>
+
+/* time headers */
+#include <time.h>
+#include <ctime>
+
+/* misc headers */
+#include "llgltfmateriallist.h"
+#include "llimage.h"
+#include "llinventoryicon.h"
+#include "llmaterialmgr.h"
+#include "llnotificationsutil.h"
+#include "llscrolllistctrl.h"
+#include "lltinygltfhelper.h"
+#include "llviewertexture.h"
+#include "tinygltf/tiny_gltf.h"
+
+/*=======================================*/
+/* Formal declarations, constants, etc. */
+/*=======================================*/
+
+static const F32 LL_LOCAL_TIMER_HEARTBEAT = 3.0;
+static const S32 LL_LOCAL_UPDATE_RETRIES = 5;
+
+/*=======================================*/
+/* LLLocalGLTFMaterial: unit class */
+/*=======================================*/
+LLLocalGLTFMaterial::LLLocalGLTFMaterial(std::string filename, S32 index)
+ : mFilename(filename)
+ , mShortName(gDirUtilp->getBaseFileName(filename, true))
+ , mValid(false)
+ , mLastModified()
+ , mLinkStatus(LS_ON)
+ , mUpdateRetries(LL_LOCAL_UPDATE_RETRIES)
+ , mMaterialIndex(index)
+{
+ mTrackingID.generate();
+
+ /* extension */
+ std::string temp_exten = gDirUtilp->getExtension(mFilename);
+
+ if (temp_exten == "gltf")
+ {
+ mExtension = ET_MATERIAL_GLTF;
+ }
+ else if (temp_exten == "glb")
+ {
+ mExtension = ET_MATERIAL_GLB;
+ }
+ else
+ {
+ LL_WARNS() << "File of no valid extension given, local material creation aborted." << "\n"
+ << "Filename: " << mFilename << LL_ENDL;
+ return; // no valid extension.
+ }
+
+ /* next phase of unit creation is nearly the same as an update cycle.
+ we're running updateSelf as a special case with the optional UT_FIRSTUSE
+ which omits the parts associated with removing the outdated texture */
+ mValid = updateSelf();
+}
+
+LLLocalGLTFMaterial::~LLLocalGLTFMaterial()
+{
+ // delete self from material list
+ gGLTFMaterialList.removeMaterial(mWorldID);
+}
+
+/* accessors */
+std::string LLLocalGLTFMaterial::getFilename()
+{
+ return mFilename;
+}
+
+std::string LLLocalGLTFMaterial::getShortName()
+{
+ return mShortName;
+}
+
+LLUUID LLLocalGLTFMaterial::getTrackingID()
+{
+ return mTrackingID;
+}
+
+LLUUID LLLocalGLTFMaterial::getWorldID()
+{
+ return mWorldID;
+}
+
+S32 LLLocalGLTFMaterial::getIndexInFile()
+{
+ return mMaterialIndex;
+}
+
+bool LLLocalGLTFMaterial::getValid()
+{
+ return mValid;
+}
+
+/* update functions */
+bool LLLocalGLTFMaterial::updateSelf()
+{
+ bool updated = false;
+
+ if (mLinkStatus == LS_ON)
+ {
+ // verifying that the file exists
+ if (gDirUtilp->fileExists(mFilename))
+ {
+ // verifying that the file has indeed been modified
+
+#ifndef LL_WINDOWS
+ const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename));
+#else
+ const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(utf8str_to_utf16str(mFilename)));
+#endif
+ LLSD new_last_modified = asctime(localtime(&temp_time));
+
+ if (mLastModified.asString() != new_last_modified.asString())
+ {
+ if (loadMaterial())
+ {
+ // decode is successful, we can safely proceed.
+ if (mWorldID.isNull())
+ {
+ mWorldID.generate();
+ }
+ mLastModified = new_last_modified;
+
+ // addMaterial will replace material witha a new
+ // pointer if value already exists but we are
+ // reusing existing pointer, so it should add only.
+ gGLTFMaterialList.addMaterial(mWorldID, mGLTFMaterial);
+
+ mUpdateRetries = LL_LOCAL_UPDATE_RETRIES;
+ updated = true;
+ }
+
+ // if decoding failed, we get here and it will attempt to decode it in the next cycles
+ // until mUpdateRetries runs out. this is done because some software lock the material while writing to it
+ else
+ {
+ if (mUpdateRetries)
+ {
+ mUpdateRetries--;
+ }
+ else
+ {
+ LL_WARNS() << "During the update process the following file was found" << "\n"
+ << "but could not be opened or decoded for " << LL_LOCAL_UPDATE_RETRIES << " attempts." << "\n"
+ << "Filename: " << mFilename << "\n"
+ << "Disabling further update attempts for this file." << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = mFilename;
+ notif_args["NRETRIES"] = LL_LOCAL_UPDATE_RETRIES;
+ LLNotificationsUtil::add("LocalBitmapsUpdateFailedFinal", notif_args);
+
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+ }
+
+ } // end if file exists
+
+ else
+ {
+ LL_WARNS() << "During the update process, the following file was not found." << "\n"
+ << "Filename: " << mFilename << "\n"
+ << "Disabling further update attempts for this file." << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = mFilename;
+ LLNotificationsUtil::add("LocalBitmapsUpdateFileNotFound", notif_args);
+
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+
+ return updated;
+}
+
+bool LLLocalGLTFMaterial::loadMaterial()
+{
+ bool decode_successful = false;
+
+ if (mWorldID.notNull())
+ {
+ // We should already have it, but update mGLTFMaterial just in case
+ // will create a new one if material doesn't exist yet
+ mGLTFMaterial = (LLFetchedGLTFMaterial*)gGLTFMaterialList.getMaterial(mWorldID);
+ }
+ else
+ {
+ mGLTFMaterial = new LLFetchedGLTFMaterial();
+ }
+
+ switch (mExtension)
+ {
+ case ET_MATERIAL_GLTF:
+ case ET_MATERIAL_GLB:
+ {
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ tinygltf::Model model_in;
+
+ std::string filename_lc = mFilename;
+ LLStringUtil::toLower(filename_lc);
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ if (std::string::npos == filename_lc.rfind(".gltf"))
+ { // file is binary
+ decode_successful = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+ else
+ { // file is ascii
+ decode_successful = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+
+ if (!decode_successful)
+ {
+ LL_WARNS() << "Cannot load Material, error: " << error_msg
+ << ", warning:" << warn_msg
+ << " file: " << mFilename
+ << LL_ENDL;
+ break;
+ }
+
+ if (model_in.materials.size() <= mMaterialIndex)
+ {
+ // materials are missing
+ LL_WARNS() << "Cannot load Material, Material " << mMaterialIndex << " is missing, " << mFilename << LL_ENDL;
+ decode_successful = false;
+ break;
+ }
+
+ // sets everything, but textures will have inaccurate ids
+ mGLTFMaterial->setFromModel(model_in, mMaterialIndex);
+
+ std::string folder = gDirUtilp->getDirName(filename_lc);
+ tinygltf::Material material_in = model_in.materials[mMaterialIndex];
+
+ if (!material_in.name.empty())
+ {
+ mShortName = gDirUtilp->getBaseFileName(filename_lc, true) + " (" + material_in.name + ")";
+ }
+
+ // get base color texture
+ LLPointer<LLImageRaw> base_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index);
+ // get normal map
+ LLPointer<LLImageRaw> normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index);
+ // get metallic-roughness texture
+ LLPointer<LLImageRaw> mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index);
+ // get emissive texture
+ LLPointer<LLImageRaw> emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index);
+ // get occlusion map if needed
+ LLPointer<LLImageRaw> occlusion_img;
+ if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index)
+ {
+ occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index);
+ }
+
+ // todo: pass it into local bitmaps?
+ LLTinyGLTFHelper::initFetchedTextures(material_in,
+ base_img, normal_img, mr_img, emissive_img, occlusion_img,
+ mBaseColorFetched, mNormalFetched, mMRFetched, mEmissiveFetched);
+
+ if (mBaseColorFetched)
+ {
+ mBaseColorFetched->addTextureStats(64.f * 64.f, TRUE);
+ mGLTFMaterial->mBaseColorId = mBaseColorFetched->getID();
+ mGLTFMaterial->mBaseColorTexture = mBaseColorFetched;
+ }
+ else
+ {
+ mGLTFMaterial->mBaseColorId = LLUUID::null;
+ mGLTFMaterial->mBaseColorTexture = nullptr;
+ }
+
+ if (mNormalFetched)
+ {
+ mNormalFetched->addTextureStats(64.f * 64.f, TRUE);
+ mGLTFMaterial->mNormalId = mNormalFetched->getID();
+ mGLTFMaterial->mNormalTexture = mBaseColorFetched;
+ }
+ else
+ {
+ mGLTFMaterial->mNormalId = LLUUID::null;
+ mGLTFMaterial->mNormalTexture = nullptr;
+ }
+
+ if (mMRFetched)
+ {
+ mMRFetched->addTextureStats(64.f * 64.f, TRUE);
+ mGLTFMaterial->mMetallicRoughnessId = mMRFetched->getID();
+ mGLTFMaterial->mMetallicRoughnessTexture = mBaseColorFetched;
+ }
+ else
+ {
+ mGLTFMaterial->mMetallicRoughnessId = LLUUID::null;
+ mGLTFMaterial->mMetallicRoughnessTexture = nullptr;
+ }
+
+ if (mEmissiveFetched)
+ {
+ mEmissiveFetched->addTextureStats(64.f * 64.f, TRUE);
+ mGLTFMaterial->mEmissiveId = mEmissiveFetched->getID();
+ mGLTFMaterial->mEmissiveTexture = mBaseColorFetched;
+ }
+ else
+ {
+ mGLTFMaterial->mEmissiveId = LLUUID::null;
+ mGLTFMaterial->mEmissiveTexture = nullptr;
+ }
+
+ break;
+ }
+
+ default:
+ {
+ // separating this into -several- LL_WARNS() calls because in the extremely unlikely case that this happens
+ // accessing mFilename and any other object properties might very well crash the viewer.
+ // getting here should be impossible, or there's been a pretty serious bug.
+
+ LL_WARNS() << "During a decode attempt, the following local material had no properly assigned extension." << LL_ENDL;
+ LL_WARNS() << "Filename: " << mFilename << LL_ENDL;
+ LL_WARNS() << "Disabling further update attempts for this file." << LL_ENDL;
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+
+ return decode_successful;
+}
+
+
+/*=======================================*/
+/* LLLocalGLTFMaterialTimer: timer class */
+/*=======================================*/
+LLLocalGLTFMaterialTimer::LLLocalGLTFMaterialTimer() : LLEventTimer(LL_LOCAL_TIMER_HEARTBEAT)
+{
+}
+
+LLLocalGLTFMaterialTimer::~LLLocalGLTFMaterialTimer()
+{
+}
+
+void LLLocalGLTFMaterialTimer::startTimer()
+{
+ mEventTimer.start();
+}
+
+void LLLocalGLTFMaterialTimer::stopTimer()
+{
+ mEventTimer.stop();
+}
+
+bool LLLocalGLTFMaterialTimer::isRunning()
+{
+ return mEventTimer.getStarted();
+}
+
+BOOL LLLocalGLTFMaterialTimer::tick()
+{
+ // todo: do on idle? No point in timer
+ LLLocalGLTFMaterialMgr::getInstance()->doUpdates();
+ return FALSE;
+}
+
+/*=======================================*/
+/* LLLocalGLTFMaterialMgr: manager class */
+/*=======================================*/
+LLLocalGLTFMaterialMgr::LLLocalGLTFMaterialMgr()
+{
+}
+
+LLLocalGLTFMaterialMgr::~LLLocalGLTFMaterialMgr()
+{
+ std::for_each(mMaterialList.begin(), mMaterialList.end(), DeletePointer());
+ mMaterialList.clear();
+}
+
+S32 LLLocalGLTFMaterialMgr::addUnit(const std::vector<std::string>& filenames)
+{
+ S32 add_count = 0;
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty())
+ {
+ add_count += addUnit(*iter);
+ }
+ iter++;
+ }
+ return add_count;
+}
+
+S32 LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)
+{
+ std::string exten = gDirUtilp->getExtension(filename);
+ S32 materials_in_file = 0;
+
+ if (exten == "gltf" || exten == "glb")
+ {
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ tinygltf::Model model_in;
+
+ std::string filename_lc = filename;
+ LLStringUtil::toLower(filename_lc);
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ bool decode_successful = false;
+ if (std::string::npos == filename_lc.rfind(".gltf"))
+ { // file is binary
+ decode_successful = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+ else
+ { // file is ascii
+ decode_successful = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+
+ if (!decode_successful)
+ {
+ LL_WARNS() << "Cannot load, error: Failed to decode" << error_msg
+ << ", warning:" << warn_msg
+ << " file: " << filename
+ << LL_ENDL;
+ return 0;
+ }
+
+ if (model_in.materials.empty())
+ {
+ // materials are missing
+ LL_WARNS() << "Cannot load. File has no materials " << filename << LL_ENDL;
+ return 0;
+ }
+ materials_in_file = model_in.materials.size();
+ }
+
+ S32 loaded_materials = 0;
+ for (S32 i = 0; i < materials_in_file; i++)
+ {
+ // Todo: this is rather inefficient, files will be spammed with
+ // separate loads and date checks, find a way to improve this.
+ // May be doUpdates() should be checking individual files.
+ LLLocalGLTFMaterial* unit = new LLLocalGLTFMaterial(filename, i);
+
+ if (unit->getValid())
+ {
+ mMaterialList.push_back(unit);
+ loaded_materials++;
+ }
+ else
+ {
+ LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
+ << "Filename: " << filename << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = filename;
+ LLNotificationsUtil::add("LocalGLTFVerifyFail", notif_args);
+
+ delete unit;
+ unit = NULL;
+ }
+ }
+
+ return loaded_materials;
+}
+
+void LLLocalGLTFMaterialMgr::delUnit(LLUUID tracking_id)
+{
+ if (!mMaterialList.empty())
+ {
+ std::vector<LLLocalGLTFMaterial*> to_delete;
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ { /* finding which ones we want deleted and making a separate list */
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ to_delete.push_back(unit);
+ }
+ }
+
+ for (std::vector<LLLocalGLTFMaterial*>::iterator del_iter = to_delete.begin();
+ del_iter != to_delete.end(); del_iter++)
+ { /* iterating over a temporary list, hence preserving the iterator validity while deleting. */
+ LLLocalGLTFMaterial* unit = *del_iter;
+ mMaterialList.remove(unit);
+ delete unit;
+ unit = NULL;
+ }
+ }
+}
+
+LLUUID LLLocalGLTFMaterialMgr::getWorldID(LLUUID tracking_id)
+{
+ LLUUID world_id = LLUUID::null;
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ world_id = unit->getWorldID();
+ }
+ }
+
+ return world_id;
+}
+
+bool LLLocalGLTFMaterialMgr::isLocal(const LLUUID world_id)
+{
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getWorldID() == world_id)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLLocalGLTFMaterialMgr::getFilenameAndIndex(LLUUID tracking_id, std::string &filename, S32 &index)
+{
+ filename = "";
+ index = 0;
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ filename = unit->getFilename();
+ index = unit->getIndexInFile();
+ }
+ }
+}
+
+// probably shouldn't be here, but at the moment this mirrors lllocalbitmaps
+void LLLocalGLTFMaterialMgr::feedScrollList(LLScrollListCtrl* ctrl)
+{
+ if (ctrl)
+ {
+ if (!mMaterialList.empty())
+ {
+ std::string icon_name = LLInventoryIcon::getIconName(
+ LLAssetType::AT_MATERIAL,
+ LLInventoryType::IT_NONE);
+
+ for (local_list_iter iter = mMaterialList.begin();
+ iter != mMaterialList.end(); iter++)
+ {
+ LLSD element;
+
+ element["columns"][0]["column"] = "icon";
+ element["columns"][0]["type"] = "icon";
+ element["columns"][0]["value"] = icon_name;
+
+ element["columns"][1]["column"] = "unit_name";
+ element["columns"][1]["type"] = "text";
+ element["columns"][1]["value"] = (*iter)->getShortName();
+
+ LLSD data;
+ data["id"] = (*iter)->getTrackingID();
+ data["type"] = (S32)LLAssetType::AT_MATERIAL;
+ element["value"] = data;
+
+ ctrl->addElement(element);
+ }
+ }
+ }
+
+}
+
+void LLLocalGLTFMaterialMgr::doUpdates()
+{
+ // preventing theoretical overlap in cases with huge number of loaded images.
+ mTimer.stopTimer();
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ (*iter)->updateSelf();
+ }
+
+ mTimer.startTimer();
+}
+
diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h
new file mode 100644
index 0000000000..097f2ea30a
--- /dev/null
+++ b/indra/newview/lllocalgltfmaterials.h
@@ -0,0 +1,129 @@
+/**
+ * @file lllocalrendermaterials.h
+ * @brief Local GLTF materials header
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LOCALGLTFMATERIALS_H
+#define LL_LOCALGLTFMATERIALS_H
+
+#include "lleventtimer.h"
+#include "llpointer.h"
+
+class LLScrollListCtrl;
+class LLGLTFMaterial;
+class LLViewerObject;
+class LLViewerFetchedTexture;
+class LLFetchedGLTFMaterial;
+
+class LLLocalGLTFMaterial
+{
+public: /* main */
+ LLLocalGLTFMaterial(std::string filename, S32 index);
+ ~LLLocalGLTFMaterial();
+
+public: /* accessors */
+ std::string getFilename();
+ std::string getShortName();
+ LLUUID getTrackingID();
+ LLUUID getWorldID();
+ S32 getIndexInFile();
+ bool getValid();
+
+public:
+ bool updateSelf();
+
+private:
+ bool loadMaterial();
+
+private: /* private enums */
+ enum ELinkStatus
+ {
+ LS_ON,
+ LS_BROKEN,
+ };
+
+ enum EExtension
+ {
+ ET_MATERIAL_GLTF,
+ ET_MATERIAL_GLB,
+ };
+
+private: /* members */
+ std::string mFilename;
+ std::string mShortName;
+ LLUUID mTrackingID;
+ LLUUID mWorldID;
+ bool mValid;
+ LLSD mLastModified;
+ EExtension mExtension;
+ ELinkStatus mLinkStatus;
+ S32 mUpdateRetries;
+ S32 mMaterialIndex; // Single file can have more than one
+
+ // Maintain textures and material pointers to
+ // make sure they won't be deleted in any way
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
+ LLPointer<LLViewerFetchedTexture> mBaseColorFetched;
+ LLPointer<LLViewerFetchedTexture> mNormalFetched;
+ LLPointer<LLViewerFetchedTexture> mMRFetched;
+ LLPointer<LLViewerFetchedTexture> mEmissiveFetched;
+};
+
+class LLLocalGLTFMaterialTimer : public LLEventTimer
+{
+public:
+ LLLocalGLTFMaterialTimer();
+ ~LLLocalGLTFMaterialTimer();
+
+public:
+ void startTimer();
+ void stopTimer();
+ bool isRunning();
+ BOOL tick();
+};
+
+class LLLocalGLTFMaterialMgr : public LLSingleton<LLLocalGLTFMaterialMgr>
+{
+ LLSINGLETON(LLLocalGLTFMaterialMgr);
+ ~LLLocalGLTFMaterialMgr();
+public:
+ S32 addUnit(const std::vector<std::string>& filenames);
+ S32 addUnit(const std::string& filename); // file can hold multiple materials
+ void delUnit(LLUUID tracking_id);
+
+ LLUUID getWorldID(LLUUID tracking_id);
+ bool isLocal(LLUUID world_id);
+ void getFilenameAndIndex(LLUUID tracking_id, std::string &filename, S32 &index);
+
+ void feedScrollList(LLScrollListCtrl* ctrl);
+ void doUpdates();
+
+private:
+ std::list<LLLocalGLTFMaterial*> mMaterialList;
+ LLLocalGLTFMaterialTimer mTimer;
+ typedef std::list<LLLocalGLTFMaterial*>::iterator local_list_iter;
+};
+
+#endif // LL_LOCALGLTFMATERIALS_H
+
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index 79dbe17982..af2a9f6afd 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -109,6 +109,8 @@ public:
LLLineEditor* getTextEntry() const { return mTextEntry; }
void handleLoginComplete();
+ bool isNavMeshDirty() { return mIsNavMeshDirty; }
+
private:
enum EParcelIcon
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index a3d0eb5796..82ecfbd4dc 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -280,7 +280,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
mRequestData["options"] = requested_options;
mRequestData["http_params"] = http_params;
#if LL_RELEASE_FOR_DOWNLOAD
- mRequestData["wait_for_updater"] = !gSavedSettings.getBOOL("CmdLineSkipUpdater") && !LLAppViewer::instance()->isUpdaterMissing();
+ mRequestData["wait_for_updater"] = LLAppViewer::instance()->waitForUpdater();
#else
mRequestData["wait_for_updater"] = false;
#endif
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index d85a846f4d..6b9543d433 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -277,7 +277,7 @@ void LLManipRotate::render()
LLGLEnable cull_face(GL_CULL_FACE);
LLGLEnable clip_plane0(GL_CLIP_PLANE0);
LLGLDepthTest gls_depth(GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
// First pass: centers. Second pass: sides.
for( S32 i=0; i<2; i++ )
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index e74fd1241b..c15f1da26b 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -757,7 +757,7 @@ void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest gls_depth(GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
gGL.pushMatrix();
{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 0b2a1ef389..b9e68bd6a9 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1063,7 +1063,7 @@ void LLManipTranslate::render()
renderGuidelines();
}
{
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderTranslationHandles();
renderSnapGuides();
}
@@ -1529,7 +1529,7 @@ void LLManipTranslate::renderSnapGuides()
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
{
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName());
@@ -1628,6 +1628,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLQuaternion grid_rotation,
LLColor4 inner_color)
{
+#if 0 // DEPRECATED
if (!gSavedSettings.getBOOL("GridCrossSections"))
{
return;
@@ -1651,13 +1652,13 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
}
{
- glStencilMask(stencil_mask);
- glClearStencil(1);
- glClear(GL_STENCIL_BUFFER_BIT);
+ //glStencilMask(stencil_mask); //deprecated
+ //glClearStencil(1);
+ //glClear(GL_STENCIL_BUFFER_BIT);
LLGLEnable cull_face(GL_CULL_FACE);
- LLGLEnable stencil(GL_STENCIL_TEST);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS);
- glStencilFunc(GL_ALWAYS, 0, stencil_mask);
+ //glStencilFunc(GL_ALWAYS, 0, stencil_mask);
gGL.setColorMask(false, false);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -1690,14 +1691,14 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
}
//stencil in volumes
- glStencilOp(GL_INCR, GL_INCR, GL_INCR);
+ //glStencilOp(GL_INCR, GL_INCR, GL_INCR);
glCullFace(GL_FRONT);
for (U32 i = 0; i < num_types; i++)
{
gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
}
- glStencilOp(GL_DECR, GL_DECR, GL_DECR);
+ //glStencilOp(GL_DECR, GL_DECR, GL_DECR);
glCullFace(GL_BACK);
for (U32 i = 0; i < num_types; i++)
{
@@ -1741,7 +1742,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest depth(GL_FALSE);
- LLGLEnable stencil(GL_STENCIL_TEST);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 0, stencil_mask);
renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f);
@@ -1752,6 +1753,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
gGL.popMatrix();
+#endif
}
void LLManipTranslate::renderText()
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 044c76ce2c..dd4ae4d201 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -758,7 +758,14 @@ void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type&
if (mMarketPlaceStatus != MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
{
// If already initialized, just confirm the status so the callback gets called
- setSLMStatus(mMarketPlaceStatus);
+ if (mMarketPlaceFailureReason.empty())
+ {
+ setSLMStatus(mMarketPlaceStatus);
+ }
+ else
+ {
+ setSLMConnectionFailure(mMarketPlaceFailureReason);
+ }
}
else
{
@@ -799,28 +806,27 @@ void LLMarketplaceData::getMerchantStatusCoro()
if (httpCode == HTTP_NOT_FOUND)
{
log_SLM_infos("Get /merchant", httpCode, std::string("User is not a merchant"));
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
}
else if (httpCode == HTTP_SERVICE_UNAVAILABLE)
{
log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated"));
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
- else if (httpCode == HTTP_INTERNAL_ERROR)
+ else
{
- // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938
LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode
<< ", reason : " << status.toString()
<< ", code : " << result["error_code"].asString()
<< ", description : " << result["error_description"].asString() << LL_ENDL;
- LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
- }
- else
- {
- std::string err_code = result["error_code"].asString();
- //std::string err_description = result["error_description"].asString();
- log_SLM_warning("Get /merchant", httpCode, status.toString(), err_code, result["error_description"]);
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+ std::string reason = status.toString();
+ if (reason.empty())
+ {
+ reason = result["error_code"].asString();
+ }
+ // Since user might not even have a marketplace, there is no reason to report the error
+ // to the user, instead write it down into listings' floater
+ LLMarketplaceData::instance().setSLMConnectionFailure(reason);
}
return;
}
@@ -1298,6 +1304,17 @@ std::string LLMarketplaceData::getSLMConnectURL(const std::string& route)
void LLMarketplaceData::setSLMStatus(U32 status)
{
mMarketPlaceStatus = status;
+ mMarketPlaceFailureReason.clear();
+ if (mStatusUpdatedSignal)
+ {
+ (*mStatusUpdatedSignal)();
+ }
+}
+
+void LLMarketplaceData::setSLMConnectionFailure(const std::string& reason)
+{
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE;
+ mMarketPlaceFailureReason = reason;
if (mStatusUpdatedSignal)
{
(*mStatusUpdatedSignal)();
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index fee9225f77..088507d850 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -198,7 +198,9 @@ public:
typedef boost::signals2::signal<void ()> status_updated_signal_t;
void initializeSLM(const status_updated_signal_t::slot_type& cb);
U32 getSLMStatus() const { return mMarketPlaceStatus; }
+ std::string getSLMConnectionfailureReason() { return mMarketPlaceFailureReason; }
void setSLMStatus(U32 status);
+ void setSLMConnectionFailure(const std::string& reason);
void getSLMListings();
bool isEmpty() { return (mMarketplaceItems.size() == 0); }
void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb);
@@ -272,6 +274,7 @@ private:
// Handling Marketplace connection and inventory connection
U32 mMarketPlaceStatus;
+ std::string mMarketPlaceFailureReason;
status_updated_signal_t* mStatusUpdatedSignal;
LLInventoryObserver* mInventoryObserver;
bool mDirtyCount; // If true, stock count value need to be updated at the next check
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
new file mode 100644
index 0000000000..a6d2729dfa
--- /dev/null
+++ b/indra/newview/llmaterialeditor.cpp
@@ -0,0 +1,2616 @@
+/**
+ * @file llmaterialeditor.cpp
+ * @brief Implementation of the gltf material editor
+ *
+ * $LicenseInfo:firstyear=2022&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmaterialeditor.h"
+
+#include "llagent.h"
+#include "llagentbenefits.h"
+#include "llappviewer.h"
+#include "llcombobox.h"
+#include "llfloaterreg.h"
+#include "llfilesystem.h"
+#include "llgltfmateriallist.h"
+#include "llinventorymodel.h"
+#include "llnotificationsutil.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewermenufile.h"
+#include "llviewertexture.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llstatusbar.h" // can_afford_transaction()
+#include "llviewerinventory.h"
+#include "llinventory.h"
+#include "llviewerregion.h"
+#include "llvovolume.h"
+#include "roles_constants.h"
+#include "llviewerobjectlist.h"
+#include "llsdserialize.h"
+#include "llimagej2c.h"
+#include "llviewertexturelist.h"
+#include "llfloaterperms.h"
+
+#include "tinygltf/tiny_gltf.h"
+#include "lltinygltfhelper.h"
+#include <strstream>
+
+
+const std::string MATERIAL_BASE_COLOR_DEFAULT_NAME = "Base Color";
+const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal";
+const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness";
+const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive";
+
+const LLUUID LIVE_MATERIAL_EDITOR_KEY("6cf97162-8b68-49eb-b627-79886c9fd17d");
+
+// Dirty flags
+static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0;
+static const U32 MATERIAL_BASE_TRANSPARENCY_DIRTY = 0x1 << 1;
+static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 2;
+
+static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 3;
+
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 4;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 5;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 6;
+
+static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 7;
+static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 8;
+
+static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9;
+static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10;
+static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11;
+
+LLFloaterComboOptions::LLFloaterComboOptions()
+ : LLFloater(LLSD())
+{
+ buildFromFile("floater_combobox_ok_cancel.xml");
+}
+
+LLFloaterComboOptions::~LLFloaterComboOptions()
+{
+
+}
+
+BOOL LLFloaterComboOptions::postBuild()
+{
+ mConfirmButton = getChild<LLButton>("combo_ok", TRUE);
+ mCancelButton = getChild<LLButton>("combo_cancel", TRUE);
+ mComboOptions = getChild<LLComboBox>("combo_options", TRUE);
+ mComboText = getChild<LLTextBox>("combo_text", TRUE);
+
+ mConfirmButton->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) {onConfirm(); });
+ mCancelButton->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) {onCancel(); });
+
+ return TRUE;
+}
+
+LLFloaterComboOptions* LLFloaterComboOptions::showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::list<std::string> &options)
+{
+ LLFloaterComboOptions* combo_picker = new LLFloaterComboOptions();
+ if (combo_picker)
+ {
+ combo_picker->mCallback = callback;
+ combo_picker->setTitle(title);
+
+ combo_picker->mComboText->setText(description);
+
+ std::list<std::string>::const_iterator iter = options.begin();
+ std::list<std::string>::const_iterator end = options.end();
+ for (; iter != end; iter++)
+ {
+ combo_picker->mComboOptions->addSimpleElement(*iter);
+ }
+ combo_picker->mComboOptions->selectFirstItem();
+
+ combo_picker->openFloater(LLSD(title));
+ combo_picker->setFocus(TRUE);
+ combo_picker->center();
+ }
+ return combo_picker;
+}
+
+LLFloaterComboOptions* LLFloaterComboOptions::showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::string &ok_text,
+ const std::string &cancel_text,
+ const std::list<std::string> &options)
+{
+ LLFloaterComboOptions* combo_picker = showUI(callback, title, description, options);
+ if (combo_picker)
+ {
+ combo_picker->mConfirmButton->setLabel(ok_text);
+ combo_picker->mCancelButton->setLabel(cancel_text);
+ }
+ return combo_picker;
+}
+
+void LLFloaterComboOptions::onConfirm()
+{
+ mCallback(mComboOptions->getSimple(), mComboOptions->getCurrentIndex());
+ closeFloater();
+}
+
+void LLFloaterComboOptions::onCancel()
+{
+ mCallback(std::string(), -1);
+ closeFloater();
+}
+
+class LLMaterialEditorCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLMaterialEditorCopiedCallback(
+ const std::string &buffer,
+ const LLSD &old_key,
+ bool has_unsaved_changes)
+ : mBuffer(buffer),
+ mOldKey(old_key),
+ mHasUnsavedChanges(has_unsaved_changes)
+ {}
+
+ LLMaterialEditorCopiedCallback(
+ const LLSD &old_key,
+ const std::string &new_name)
+ : mOldKey(old_key),
+ mNewName(new_name),
+ mHasUnsavedChanges(false)
+ {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mNewName.empty())
+ {
+ // making a copy from a notecard doesn't change name, do it now
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item->getName() != mNewName)
+ {
+ LLSD updates;
+ updates["name"] = mNewName;
+ update_inventory_item(inv_item_id, updates, NULL);
+ }
+ }
+ LLMaterialEditor::finishSaveAs(mOldKey, inv_item_id, mBuffer, mHasUnsavedChanges);
+ }
+
+private:
+ std::string mBuffer;
+ LLSD mOldKey;
+ std::string mNewName;
+ bool mHasUnsavedChanges;
+};
+
+///----------------------------------------------------------------------------
+/// Class LLMaterialEditor
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLMaterialEditor::LLMaterialEditor(const LLSD& key)
+ : LLPreview(key)
+ , mUnsavedChanges(0)
+ , mExpectedUploadCost(0)
+ , mUploadingTexturesCount(0)
+{
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+void LLMaterialEditor::setObjectID(const LLUUID& object_id)
+{
+ LLPreview::setObjectID(object_id);
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+void LLMaterialEditor::setAuxItem(const LLInventoryItem* item)
+{
+ LLPreview::setAuxItem(item);
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+BOOL LLMaterialEditor::postBuild()
+{
+ mBaseColorTextureCtrl = getChild<LLTextureCtrl>("base_color_texture");
+ mMetallicTextureCtrl = getChild<LLTextureCtrl>("metallic_roughness_texture");
+ mEmissiveTextureCtrl = getChild<LLTextureCtrl>("emissive_texture");
+ mNormalTextureCtrl = getChild<LLTextureCtrl>("normal_texture");
+
+ mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitBaseColorTexture, this, _1, _2));
+ mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2));
+ mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2));
+ mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2));
+
+ childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this));
+ childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this));
+ childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this));
+
+ S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+ getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+
+ boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void* userData)
+ {
+ const U32 *flag = (const U32*)userData;
+ markChangesUnsaved(*flag);
+ // Apply changes to object live
+ applyToSelection();
+ };
+
+ childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY);
+
+ // BaseColor
+ childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY);
+ childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_TRANSPARENCY_DIRTY);
+ childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY);
+ childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY);
+
+ // Metallic-Roughness
+ childSetCommitCallback("metalness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY);
+ childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY);
+
+ // Emissive
+ childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY);
+
+ childSetVisible("unsaved_changes", mUnsavedChanges);
+
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0));
+
+ // Todo:
+ // Disable/enable setCanApplyImmediately() based on
+ // working from inventory, upload or editing inworld
+
+ return LLPreview::postBuild();
+}
+
+void LLMaterialEditor::onClickCloseBtn(bool app_quitting)
+{
+ if (app_quitting)
+ {
+ closeFloater(app_quitting);
+ }
+ else
+ {
+ onClickCancel();
+ }
+}
+
+void LLMaterialEditor::onClose(bool app_quitting)
+{
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
+
+ LLPreview::onClose(app_quitting);
+}
+
+LLUUID LLMaterialEditor::getBaseColorId()
+{
+ return mBaseColorTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setBaseColorId(const LLUUID& id)
+{
+ mBaseColorTextureCtrl->setValue(id);
+ mBaseColorTextureCtrl->setDefaultImageAssetID(id);
+ mBaseColorTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id)
+{
+ // Might be better to use local textures and
+ // assign a fee in case of a local texture
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("base_color_upload_fee", getString("upload_fee_string"));
+ // Only set if we will need to upload this texture
+ mBaseColorTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY);
+}
+
+LLColor4 LLMaterialEditor::getBaseColor()
+{
+ LLColor4 ret = linearColor4(LLColor4(childGetValue("base color")));
+ ret.mV[3] = getTransparency();
+ return ret;
+}
+
+void LLMaterialEditor::setBaseColor(const LLColor4& color)
+{
+ childSetValue("base color", srgbColor4(color).getValue());
+ setTransparency(color.mV[3]);
+}
+
+F32 LLMaterialEditor::getTransparency()
+{
+ return childGetValue("transparency").asReal();
+}
+
+void LLMaterialEditor::setTransparency(F32 transparency)
+{
+ childSetValue("transparency", transparency);
+}
+
+std::string LLMaterialEditor::getAlphaMode()
+{
+ return childGetValue("alpha mode").asString();
+}
+
+void LLMaterialEditor::setAlphaMode(const std::string& alpha_mode)
+{
+ childSetValue("alpha mode", alpha_mode);
+}
+
+F32 LLMaterialEditor::getAlphaCutoff()
+{
+ return childGetValue("alpha cutoff").asReal();
+}
+
+void LLMaterialEditor::setAlphaCutoff(F32 alpha_cutoff)
+{
+ childSetValue("alpha cutoff", alpha_cutoff);
+}
+
+void LLMaterialEditor::setMaterialName(const std::string &name)
+{
+ setTitle(name);
+ mMaterialName = name;
+}
+
+LLUUID LLMaterialEditor::getMetallicRoughnessId()
+{
+ return mMetallicTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id)
+{
+ mMetallicTextureCtrl->setValue(id);
+ mMetallicTextureCtrl->setDefaultImageAssetID(id);
+ mMetallicTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("metallic_upload_fee", getString("upload_fee_string"));
+ mMetallicTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+}
+
+F32 LLMaterialEditor::getMetalnessFactor()
+{
+ return childGetValue("metalness factor").asReal();
+}
+
+void LLMaterialEditor::setMetalnessFactor(F32 factor)
+{
+ childSetValue("metalness factor", factor);
+}
+
+F32 LLMaterialEditor::getRoughnessFactor()
+{
+ return childGetValue("roughness factor").asReal();
+}
+
+void LLMaterialEditor::setRoughnessFactor(F32 factor)
+{
+ childSetValue("roughness factor", factor);
+}
+
+LLUUID LLMaterialEditor::getEmissiveId()
+{
+ return mEmissiveTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setEmissiveId(const LLUUID& id)
+{
+ mEmissiveTextureCtrl->setValue(id);
+ mEmissiveTextureCtrl->setDefaultImageAssetID(id);
+ mEmissiveTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("emissive_upload_fee", getString("upload_fee_string"));
+ mEmissiveTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY);
+}
+
+LLColor4 LLMaterialEditor::getEmissiveColor()
+{
+ return linearColor4(LLColor4(childGetValue("emissive color")));
+}
+
+void LLMaterialEditor::setEmissiveColor(const LLColor4& color)
+{
+ childSetValue("emissive color", srgbColor4(color).getValue());
+}
+
+LLUUID LLMaterialEditor::getNormalId()
+{
+ return mNormalTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setNormalId(const LLUUID& id)
+{
+ mNormalTextureCtrl->setValue(id);
+ mNormalTextureCtrl->setDefaultImageAssetID(id);
+ mNormalTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setNormalUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("normal_upload_fee", getString("upload_fee_string"));
+ mNormalTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY);
+}
+
+bool LLMaterialEditor::getDoubleSided()
+{
+ return childGetValue("double sided").asBoolean();
+}
+
+void LLMaterialEditor::setDoubleSided(bool double_sided)
+{
+ childSetValue("double sided", double_sided);
+}
+
+void LLMaterialEditor::resetUnsavedChanges()
+{
+ mUnsavedChanges = 0;
+ childSetVisible("unsaved_changes", false);
+ setCanSave(false);
+
+ mExpectedUploadCost = 0;
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
+}
+
+void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag)
+{
+ mUnsavedChanges |= dirty_flag;
+ childSetVisible("unsaved_changes", mUnsavedChanges);
+
+ if (mUnsavedChanges)
+ {
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ LLPermissions perm(item->getPermissions());
+ bool allow_modify = canModify(mObjectUUID, item);
+ bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+ bool source_notecard = mNotecardInventoryID.notNull();
+
+ setCanSave(allow_modify && !source_library && !source_notecard);
+ }
+ }
+ else
+ {
+ setCanSave(false);
+ }
+
+ S32 upload_texture_count = 0;
+ if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId())
+ {
+ upload_texture_count++;
+ }
+ if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId())
+ {
+ upload_texture_count++;
+ }
+ if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId())
+ {
+ upload_texture_count++;
+ }
+ if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId())
+ {
+ upload_texture_count++;
+ }
+
+ mExpectedUploadCost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost();
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
+}
+
+void LLMaterialEditor::setCanSaveAs(bool value)
+{
+ childSetEnabled("save_as", value);
+}
+
+void LLMaterialEditor::setCanSave(bool value)
+{
+ childSetEnabled("save", value);
+}
+
+void LLMaterialEditor::setEnableEditing(bool can_modify)
+{
+ childSetEnabled("double sided", can_modify);
+
+ // BaseColor
+ childSetEnabled("base color", can_modify);
+ childSetEnabled("transparency", can_modify);
+ childSetEnabled("alpha mode", can_modify);
+ childSetEnabled("alpha cutoff", can_modify);
+
+ // Metallic-Roughness
+ childSetEnabled("metalness factor", can_modify);
+ childSetEnabled("roughness factor", can_modify);
+
+ // Metallic-Roughness
+ childSetEnabled("metalness factor", can_modify);
+ childSetEnabled("roughness factor", can_modify);
+
+ // Emissive
+ childSetEnabled("emissive color", can_modify);
+
+ mBaseColorTextureCtrl->setEnabled(can_modify);
+ mMetallicTextureCtrl->setEnabled(can_modify);
+ mEmissiveTextureCtrl->setEnabled(can_modify);
+ mNormalTextureCtrl->setEnabled(can_modify);
+}
+
+void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data)
+{
+ // might be better to use arrays, to have a single callback
+ // and not to repeat the same thing for each tecture control
+ LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID();
+ if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull())
+ {
+ childSetValue("base_color_upload_fee", getString("upload_fee_string"));
+ }
+ else
+ {
+ // Texture picker has 'apply now' with 'cancel' support.
+ // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in
+ // case user decides to cancel changes.
+ // Without mBaseColorFetched, viewer will eventually cleanup
+ // the texture that is not in use
+ childSetValue("base_color_upload_fee", getString("no_upload_fee_string"));
+ }
+ markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY);
+ applyToSelection();
+}
+
+void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data)
+{
+ LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID();
+ if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull())
+ {
+ childSetValue("metallic_upload_fee", getString("upload_fee_string"));
+ }
+ else
+ {
+ childSetValue("metallic_upload_fee", getString("no_upload_fee_string"));
+ }
+ markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+ applyToSelection();
+}
+
+void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data)
+{
+ LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID();
+ if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull())
+ {
+ childSetValue("emissive_upload_fee", getString("upload_fee_string"));
+ }
+ else
+ {
+ childSetValue("emissive_upload_fee", getString("no_upload_fee_string"));
+ }
+ markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY);
+ applyToSelection();
+}
+
+void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data)
+{
+ LLUUID new_val = mNormalTextureCtrl->getValue().asUUID();
+ if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull())
+ {
+ childSetValue("normal_upload_fee", getString("upload_fee_string"));
+ }
+ else
+ {
+ childSetValue("normal_upload_fee", getString("no_upload_fee_string"));
+ }
+ markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY);
+ applyToSelection();
+}
+
+
+static void write_color(const LLColor4& color, std::vector<double>& c)
+{
+ for (int i = 0; i < c.size(); ++i) // NOTE -- use c.size because some gltf colors are 3-component
+ {
+ c[i] = color.mV[i];
+ }
+}
+
+static U32 write_texture(const LLUUID& id, tinygltf::Model& model)
+{
+ tinygltf::Image image;
+ image.uri = id.asString();
+ model.images.push_back(image);
+ U32 image_idx = model.images.size() - 1;
+
+ tinygltf::Texture texture;
+ texture.source = image_idx;
+ model.textures.push_back(texture);
+ U32 texture_idx = model.textures.size() - 1;
+
+ return texture_idx;
+}
+
+
+void LLMaterialEditor::onClickSave()
+{
+ if (!can_afford_transaction(mExpectedUploadCost))
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", mExpectedUploadCost);
+ LLNotificationsUtil::add("ErrorCannotAffordUpload", args);
+ return;
+ }
+
+ applyToSelection();
+ saveIfNeeded();
+}
+
+
+std::string LLMaterialEditor::getGLTFJson(bool prettyprint)
+{
+ tinygltf::Model model;
+ getGLTFModel(model);
+
+ std::ostringstream str;
+
+ tinygltf::TinyGLTF gltf;
+
+ gltf.WriteGltfSceneToStream(&model, str, prettyprint, false);
+
+ std::string dump = str.str();
+
+ return dump;
+}
+
+void LLMaterialEditor::getGLBData(std::vector<U8>& data)
+{
+ tinygltf::Model model;
+ getGLTFModel(model);
+
+ std::ostringstream str;
+
+ tinygltf::TinyGLTF gltf;
+
+ gltf.WriteGltfSceneToStream(&model, str, false, true);
+
+ std::string dump = str.str();
+
+ data.resize(dump.length());
+
+ memcpy(&data[0], dump.c_str(), dump.length());
+}
+
+void LLMaterialEditor::getGLTFModel(tinygltf::Model& model)
+{
+ model.materials.resize(1);
+ tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness;
+
+ // write base color
+ LLColor4 base_color = getBaseColor();
+ base_color.mV[3] = getTransparency();
+ write_color(base_color, pbrMaterial.baseColorFactor);
+
+ model.materials[0].alphaCutoff = getAlphaCutoff();
+ model.materials[0].alphaMode = getAlphaMode();
+
+ LLUUID base_color_id = getBaseColorId();
+
+ if (base_color_id.notNull())
+ {
+ U32 texture_idx = write_texture(base_color_id, model);
+
+ pbrMaterial.baseColorTexture.index = texture_idx;
+ }
+
+ // write metallic/roughness
+ F32 metalness = getMetalnessFactor();
+ F32 roughness = getRoughnessFactor();
+
+ pbrMaterial.metallicFactor = metalness;
+ pbrMaterial.roughnessFactor = roughness;
+
+ LLUUID mr_id = getMetallicRoughnessId();
+ if (mr_id.notNull())
+ {
+ U32 texture_idx = write_texture(mr_id, model);
+ pbrMaterial.metallicRoughnessTexture.index = texture_idx;
+ }
+
+ //write emissive
+ LLColor4 emissive_color = getEmissiveColor();
+ model.materials[0].emissiveFactor.resize(3);
+ write_color(emissive_color, model.materials[0].emissiveFactor);
+
+ LLUUID emissive_id = getEmissiveId();
+ if (emissive_id.notNull())
+ {
+ U32 idx = write_texture(emissive_id, model);
+ model.materials[0].emissiveTexture.index = idx;
+ }
+
+ //write normal
+ LLUUID normal_id = getNormalId();
+ if (normal_id.notNull())
+ {
+ U32 idx = write_texture(normal_id, model);
+ model.materials[0].normalTexture.index = idx;
+ }
+
+ //write doublesided
+ model.materials[0].doubleSided = getDoubleSided();
+
+ model.asset.version = "2.0";
+}
+
+std::string LLMaterialEditor::getEncodedAsset()
+{
+ LLSD asset;
+ asset["version"] = "1.0";
+ asset["type"] = "GLTF 2.0";
+ asset["data"] = getGLTFJson(false);
+
+ std::ostringstream str;
+ LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY);
+
+ return str.str();
+}
+
+bool LLMaterialEditor::decodeAsset(const std::vector<char>& buffer)
+{
+ LLSD asset;
+
+ std::istrstream str(&buffer[0], buffer.size());
+ if (LLSDSerialize::deserialize(asset, str, buffer.size()))
+ {
+ if (asset.has("version") && asset["version"] == "1.0")
+ {
+ if (asset.has("type") && asset["type"] == "GLTF 2.0")
+ {
+ if (asset.has("data") && asset["data"].isString())
+ {
+ std::string data = asset["data"];
+
+ tinygltf::TinyGLTF gltf;
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ tinygltf::Model model_in;
+
+ if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), ""))
+ {
+ // assets are only supposed to have one item
+ return setFromGltfModel(model_in, 0, true);
+ }
+ else
+ {
+ LL_WARNS() << "Failed to decode material asset: " << LL_ENDL;
+ LL_WARNS() << warn_msg << LL_ENDL;
+ LL_WARNS() << error_msg << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL;
+ }
+
+ return false;
+}
+
+/**
+ * Build a description of the material we just imported.
+ * Currently this means a list of the textures present but we
+ * may eventually want to make it more complete - will be guided
+ * by what the content creators say they need.
+ */
+const std::string LLMaterialEditor::buildMaterialDescription()
+{
+ std::ostringstream desc;
+ desc << LLTrans::getString("Material Texture Name Header");
+
+ // add the texture names for each just so long as the material
+ // we loaded has an entry for it (i think testing the texture
+ // control UUI for NULL is a valid metric for if it was loaded
+ // or not but I suspect this code will change a lot so may need
+ // to revisit
+ if (!mBaseColorTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mBaseColorName;
+ desc << ", ";
+ }
+ if (!mMetallicTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mMetallicRoughnessName;
+ desc << ", ";
+ }
+ if (!mEmissiveTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mEmissiveName;
+ desc << ", ";
+ }
+ if (!mNormalTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mNormalName;
+ }
+
+ // trim last char if it's a ',' in case there is no normal texture
+ // present and the code above inserts one
+ // (no need to check for string length - always has initial string)
+ std::string::iterator iter = desc.str().end() - 1;
+ if (*iter == ',')
+ {
+ desc.str().erase(iter);
+ }
+
+ // sanitize the material description so that it's compatible with the inventory
+ // note: split this up because clang doesn't like operating directly on the
+ // str() - error: lvalue reference to type 'basic_string<...>' cannot bind to a
+ // temporary of type 'basic_string<...>'
+ std::string inv_desc = desc.str();
+ LLInventoryObject::correctInventoryName(inv_desc);
+
+ return inv_desc;
+}
+
+bool LLMaterialEditor::saveIfNeeded()
+{
+ if (mUploadingTexturesCount > 0)
+ {
+ // upload already in progress
+ // wait until textures upload
+ // will retry saving on callback
+ return true;
+ }
+
+ if (saveTextures() > 0)
+ {
+ // started texture upload
+ setEnabled(false);
+ return true;
+ }
+
+ std::string buffer = getEncodedAsset();
+
+ const LLInventoryItem* item = getItem();
+ // save it out to database
+ if (item)
+ {
+ if (!saveToInventoryItem(buffer, mItemUUID, mObjectUUID))
+ {
+ return false;
+ }
+
+ if (mCloseAfterSave)
+ {
+ closeFloater();
+ }
+ else
+ {
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ setEnabled(false);
+ }
+ }
+ else
+ { //make a new inventory item
+#if 1
+ // gen a new uuid for this asset
+ LLTransactionID tid;
+ tid.generate(); // timestamp-based randomization + uniquification
+ LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+ std::string res_desc = buildMaterialDescription();
+ U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials");
+ LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ?
+
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc,
+ LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm,
+ new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item)
+ {
+ // create_inventory_item doesn't allow presetting some permissions, fix it now
+ LLPermissions perm = item->getPermissions();
+ if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Materials")
+ || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Materials"))
+ {
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials"));
+
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+
+ // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem()
+ LLResourceUploadInfo::ptr_t uploadInfo =
+ std::make_shared<LLBufferedAssetUploadInfo>(
+ inv_item_id,
+ LLAssetType::AT_MATERIAL,
+ output,
+ [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) {
+ LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL;
+ LLSD params = llsd::map("ASSET_ID", new_asset_id);
+ LLNotificationsUtil::add("MaterialCreated", params);
+ });
+
+ // todo: apply permissions from textures here if server doesn't
+ // if any texture is 'no transfer', material should be 'no transfer' as well
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string agent_url(region->getCapability("UpdateMaterialAgentInventory"));
+ if (agent_url.empty())
+ {
+ LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL;
+ }
+ LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
+ }
+ })
+ );
+
+ // We do not update floater with uploaded asset yet, so just close it.
+ closeFloater();
+#endif
+ }
+
+ return true;
+}
+
+// static
+bool LLMaterialEditor::saveToInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id)
+{
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ LL_WARNS() << "Not connected to a region, cannot save material." << LL_ENDL;
+ return false;
+ }
+ std::string agent_url = region->getCapability("UpdateMaterialAgentInventory");
+ std::string task_url = region->getCapability("UpdateMaterialTaskInventory");
+
+ if (!agent_url.empty() && !task_url.empty())
+ {
+ std::string url;
+ LLResourceUploadInfo::ptr_t uploadInfo;
+
+ if (task_id.isNull() && !agent_url.empty())
+ {
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(item_id, LLAssetType::AT_MATERIAL, buffer,
+ [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) {
+ LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId);
+ });
+ url = agent_url;
+ }
+ else if (!task_id.isNull() && !task_url.empty())
+ {
+ LLUUID object_uuid(task_id);
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(task_id, item_id, LLAssetType::AT_MATERIAL, buffer,
+ [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) {
+ LLMaterialEditor::finishTaskUpload(itemId, newAssetId, object_uuid);
+ });
+ url = task_url;
+ }
+
+ if (!url.empty() && uploadInfo)
+ {
+ LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
+ }
+ else
+ {
+ return false;
+ }
+
+ }
+ else // !gAssetStorage
+ {
+ LL_WARNS() << "Not connected to an materials capable region." << LL_ENDL;
+ return false;
+ }
+
+ // todo: apply permissions from textures here if server doesn't
+ // if any texture is 'no transfer', material should be 'no transfer' as well
+
+ return true;
+}
+
+void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId)
+{
+ // Update the UI with the new asset.
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(itemId));
+ if (me)
+ {
+ if (newItemId.isNull())
+ {
+ me->setAssetId(newAssetId);
+ me->refreshFromInventory();
+ }
+ else if (newItemId.notNull())
+ {
+ // Not supposed to happen?
+ me->refreshFromInventory(newItemId);
+ }
+ else
+ {
+ me->refreshFromInventory(itemId);
+ }
+ }
+}
+
+void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId)
+{
+ LLSD floater_key;
+ floater_key["taskid"] = taskId;
+ floater_key["itemid"] = itemId;
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (me)
+ {
+ me->setAssetId(newAssetId);
+ me->refreshFromInventory();
+ me->setEnabled(true);
+ }
+}
+
+void LLMaterialEditor::finishSaveAs(
+ const LLSD &oldKey,
+ const LLUUID &newItemId,
+ const std::string &buffer,
+ bool has_unsaved_changes)
+{
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", oldKey);
+ LLViewerInventoryItem* item = gInventory.getItem(newItemId);
+ if (item)
+ {
+ if (me)
+ {
+ me->mItemUUID = newItemId;
+ me->mObjectUUID = LLUUID::null;
+ me->mNotecardInventoryID = LLUUID::null;
+ me->mNotecardObjectID = LLUUID::null;
+ me->mAuxItem = nullptr;
+ me->setKey(LLSD(newItemId)); // for findTypedInstance
+ me->setMaterialName(item->getName());
+ if (has_unsaved_changes)
+ {
+ if (!saveToInventoryItem(buffer, newItemId, LLUUID::null))
+ {
+ me->setEnabled(true);
+ }
+ }
+ else
+ {
+ me->loadAsset();
+ me->setEnabled(true);
+ }
+ }
+ else if(has_unsaved_changes)
+ {
+ saveToInventoryItem(buffer, newItemId, LLUUID::null);
+ }
+ }
+ else if (me)
+ {
+ me->setEnabled(true);
+ LL_WARNS() << "Item does not exist" << LL_ENDL;
+ }
+}
+
+void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id)
+{
+ if (new_item_id.notNull())
+ {
+ mItemUUID = new_item_id;
+ if (mNotecardInventoryID.notNull())
+ {
+ LLSD floater_key;
+ floater_key["objectid"] = mNotecardObjectID;
+ floater_key["notecardid"] = mNotecardInventoryID;
+ setKey(floater_key);
+ }
+ else if (mObjectUUID.notNull())
+ {
+ LLSD floater_key;
+ floater_key["taskid"] = new_item_id;
+ floater_key["itemid"] = mObjectUUID;
+ setKey(floater_key);
+ }
+ else
+ {
+ setKey(LLSD(new_item_id));
+ }
+ }
+ LL_DEBUGS() << "LLPreviewNotecard::refreshFromInventory()" << LL_ENDL;
+ loadAsset();
+}
+
+
+void LLMaterialEditor::onClickSaveAs()
+{
+ if (!can_afford_transaction(mExpectedUploadCost))
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", mExpectedUploadCost);
+ LLNotificationsUtil::add("ErrorCannotAffordUpload", args);
+ return;
+ }
+
+ LLSD args;
+ args["DESC"] = mMaterialName;
+
+ LLNotificationsUtil::add("SaveMaterialAs", args, LLSD(), boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2));
+}
+
+void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ std::string new_name = response["message"].asString();
+ LLInventoryObject::correctInventoryName(new_name);
+ if (!new_name.empty())
+ {
+ const LLInventoryItem* item;
+ if (mNotecardInventoryID.notNull())
+ {
+ item = mAuxItem.get();
+ }
+ else
+ {
+ item = getItem();
+ }
+ if (item)
+ {
+ const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ LLUUID parent_id = item->getParentUUID();
+ if (mObjectUUID.notNull() || marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID()))
+ {
+ parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ }
+
+ // A two step process, first copy an existing item, then create new asset
+ if (mNotecardInventoryID.notNull())
+ {
+ LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(getKey(), new_name);
+ copy_inventory_from_notecard(parent_id,
+ mNotecardObjectID,
+ mNotecardInventoryID,
+ mAuxItem.get(),
+ gInventoryCallbacks.registerCB(cb));
+ }
+ else
+ {
+ std::string buffer = getEncodedAsset();
+ LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mUnsavedChanges);
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ parent_id,
+ new_name,
+ cb);
+ }
+
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ setEnabled(false);
+ }
+ else
+ {
+ setMaterialName(new_name);
+ onClickSave();
+ }
+ }
+ else
+ {
+ LLNotificationsUtil::add("InvalidMaterialName");
+ }
+ }
+}
+
+void LLMaterialEditor::onClickCancel()
+{
+ if (mUnsavedChanges)
+ {
+ LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2));
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ if (mIsOverride && !mObjectOverridesSavedValues.empty())
+ {
+ // Reapply ids back onto selection.
+ // TODO: monitor selection changes and resave on selection changes
+ struct g : public LLSelectedObjectFunctor
+ {
+ g(LLMaterialEditor* me) : mEditor(me) {}
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ if (!objectp || !objectp->permModify())
+ {
+ return false;
+ }
+
+ U32 local_id = objectp->getLocalID();
+ if (mEditor->mObjectOverridesSavedValues.find(local_id) == mEditor->mObjectOverridesSavedValues.end())
+ {
+ return false;
+ }
+
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ for (U8 te = 0; te < num_tes; te++)
+ {
+ if (mEditor->mObjectOverridesSavedValues[local_id].size() > te
+ && objectp->getTE(te)->isSelected())
+ {
+ objectp->setRenderMaterialID(
+ te,
+ mEditor->mObjectOverridesSavedValues[local_id][te],
+ false /*wait for bulk update*/);
+ }
+ }
+ return true;
+ }
+ LLMaterialEditor* mEditor;
+ } restorefunc(this);
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&restorefunc);
+
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object && !object->permModify())
+ {
+ return false;
+ }
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ object->setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+
+ object->sendTEUpdate();
+ return true;
+ }
+ } sendfunc;
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
+ }
+
+ closeFloater();
+ }
+}
+
+static void pack_textures(
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLImageJ2C>& base_color_j2c,
+ LLPointer<LLImageJ2C>& normal_j2c,
+ LLPointer<LLImageJ2C>& mr_j2c,
+ LLPointer<LLImageJ2C>& emissive_j2c)
+{
+ // NOTE : remove log spam and lossless vs lossy comparisons when the logs are no longer useful
+
+ if (base_color_img)
+ {
+ base_color_j2c = LLViewerTextureList::convertToUploadFile(base_color_img);
+ LL_INFOS() << "BaseColor: " << base_color_j2c->getDataSize() << LL_ENDL;
+ }
+
+ if (normal_img)
+ {
+ normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img);
+
+ LLPointer<LLImageJ2C> test;
+ test = LLViewerTextureList::convertToUploadFile(normal_img, 1024, true);
+
+ S32 lossy_bytes = normal_j2c->getDataSize();
+ S32 lossless_bytes = test->getDataSize();
+
+ LL_INFOS() << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL;
+
+ normal_j2c = test;
+ }
+
+ if (mr_img)
+ {
+ mr_j2c = LLViewerTextureList::convertToUploadFile(mr_img);
+ LL_INFOS() << "Metallic/Roughness: " << mr_j2c->getDataSize() << LL_ENDL;
+ }
+
+ if (emissive_img)
+ {
+ emissive_j2c = LLViewerTextureList::convertToUploadFile(emissive_img);
+ LL_INFOS() << "Emissive: " << emissive_j2c->getDataSize() << LL_ENDL;
+ }
+}
+
+void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index)
+{
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ bool loaded = false;
+ tinygltf::Model model_in;
+
+ std::string filename_lc = filename;
+ LLStringUtil::toLower(filename_lc);
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ if (std::string::npos == filename_lc.rfind(".gltf"))
+ { // file is binary
+ loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename);
+ }
+ else
+ { // file is ascii
+ loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename);
+ }
+
+ if (!loaded)
+ {
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ if (model_in.materials.empty())
+ {
+ // materials are missing
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ if (index >= 0 && model_in.materials.size() <= index)
+ {
+ // material is missing
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
+
+ if (index >= 0)
+ {
+ // Prespecified material
+ me->loadMaterial(model_in, filename_lc, index);
+ }
+ else if (model_in.materials.size() == 1)
+ {
+ // Only one, just load it
+ me->loadMaterial(model_in, filename_lc, 0);
+ }
+ else
+ {
+ // Promt user to select material
+ std::list<std::string> material_list;
+ std::vector<tinygltf::Material>::const_iterator mat_iter = model_in.materials.begin();
+ std::vector<tinygltf::Material>::const_iterator mat_end = model_in.materials.end();
+ for (; mat_iter != mat_end; mat_iter++)
+ {
+ std::string mat_name = mat_iter->name;
+ if (mat_name.empty())
+ {
+ material_list.push_back("Material " + std::to_string(material_list.size()));
+ }
+ else
+ {
+ material_list.push_back(mat_name);
+ }
+ }
+ LLFloaterComboOptions::showUI(
+ [me, model_in, filename_lc](const std::string& option, S32 index)
+ {
+ me->loadMaterial(model_in, filename_lc, index);
+ },
+ me->getString("material_selection_title"),
+ me->getString("material_selection_text"),
+ material_list
+ );
+ }
+}
+void LLMaterialEditor::onSelectionChanged()
+{
+ mUnsavedChanges = 0;
+ clearTextures();
+ setFromSelection();
+ saveLiveValues();
+}
+
+void LLMaterialEditor::saveLiveValues()
+{
+ // Collect ids to be able to revert overrides.
+ // TODO: monitor selection changes and resave on selection changes
+ mObjectOverridesSavedValues.clear();
+ struct g : public LLSelectedObjectFunctor
+ {
+ g(LLMaterialEditor* me) : mEditor(me) {}
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ if (!objectp)
+ {
+ return false;
+ }
+
+ U32 local_id = objectp->getLocalID();
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ for (U8 te = 0; te < num_tes; te++)
+ {
+ LLUUID mat_id = objectp->getRenderMaterialID(te);
+ mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id);
+ }
+ return true;
+ }
+ LLMaterialEditor* mEditor;
+ } savefunc(this);
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc);
+}
+
+void LLMaterialEditor::loadLive()
+{
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY));
+ if (me)
+ {
+ me->setFromSelection();
+ me->mIsOverride = true;
+ me->setTitle(me->getString("material_override_title"));
+ me->childSetVisible("save", false);
+ me->childSetVisible("save_as", false);
+
+ // Set up for selection changes updates
+ if (!me->mSelectionUpdateSlot.connected())
+ {
+ me->mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLMaterialEditor::onSelectionChanged, me));
+ }
+ // Collect ids to be able to revert overrides on cancel.
+ me->saveLiveValues();
+
+ me->openFloater();
+ me->setFocus(TRUE);
+ }
+}
+
+void LLMaterialEditor::loadObjectSave()
+{
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY));
+ if (me->setFromSelection())
+ {
+ me->mIsOverride = false;
+ me->childSetVisible("save", false);
+ me->openFloater();
+ me->setFocus(TRUE);
+ }
+}
+
+void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id)
+{
+ if (asset_id.isNull())
+ {
+ LL_WARNS() << "Trying to open material with null id" << LL_ENDL;
+ return;
+ }
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
+ me->mMaterialName = LLTrans::getString("New Material");
+ me->setTitle(me->mMaterialName);
+ me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id));
+ me->openFloater();
+ me->setFocus(TRUE);
+}
+
+void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index)
+{
+ if (model_in.materials.size() <= index)
+ {
+ return;
+ }
+ std::string folder = gDirUtilp->getDirName(filename_lc);
+
+ tinygltf::Material material_in = model_in.materials[index];
+
+ tinygltf::Model model_out;
+ model_out.asset.version = "2.0";
+ model_out.materials.resize(1);
+
+ // get base color texture
+ LLPointer<LLImageRaw> base_color_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mBaseColorName);
+ // get normal map
+ LLPointer<LLImageRaw> normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, mNormalName);
+ // get metallic-roughness texture
+ LLPointer<LLImageRaw> mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, mMetallicRoughnessName);
+ // get emissive texture
+ LLPointer<LLImageRaw> emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index, mEmissiveName);
+ // get occlusion map if needed
+ LLPointer<LLImageRaw> occlusion_img;
+ if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index)
+ {
+ std::string tmp;
+ occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index, tmp);
+ }
+
+ LLTinyGLTFHelper::initFetchedTextures(material_in, base_color_img, normal_img, mr_img, emissive_img, occlusion_img,
+ mBaseColorFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched);
+ pack_textures(base_color_img, normal_img, mr_img, emissive_img, occlusion_img,
+ mBaseColorJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C);
+
+ LLUUID base_color_id;
+ if (mBaseColorFetched.notNull())
+ {
+ mBaseColorFetched->forceToSaveRawImage(0, F32_MAX);
+ base_color_id = mBaseColorFetched->getID();
+
+ if (mBaseColorName.empty())
+ {
+ mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID normal_id;
+ if (mNormalFetched.notNull())
+ {
+ mNormalFetched->forceToSaveRawImage(0, F32_MAX);
+ normal_id = mNormalFetched->getID();
+
+ if (mNormalName.empty())
+ {
+ mNormalName = MATERIAL_NORMAL_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID mr_id;
+ if (mMetallicRoughnessFetched.notNull())
+ {
+ mMetallicRoughnessFetched->forceToSaveRawImage(0, F32_MAX);
+ mr_id = mMetallicRoughnessFetched->getID();
+
+ if (mMetallicRoughnessName.empty())
+ {
+ mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID emissive_id;
+ if (mEmissiveFetched.notNull())
+ {
+ mEmissiveFetched->forceToSaveRawImage(0, F32_MAX);
+ emissive_id = mEmissiveFetched->getID();
+
+ if (mEmissiveName.empty())
+ {
+ mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME;
+ }
+ }
+
+ setBaseColorId(base_color_id);
+ setBaseColorUploadId(base_color_id);
+ setMetallicRoughnessId(mr_id);
+ setMetallicRoughnessUploadId(mr_id);
+ setEmissiveId(emissive_id);
+ setEmissiveUploadId(emissive_id);
+ setNormalId(normal_id);
+ setNormalUploadId(normal_id);
+
+ setFromGltfModel(model_in, index);
+
+ setFromGltfMetaData(filename_lc, model_in, index);
+
+ markChangesUnsaved(U32_MAX);
+
+ openFloater();
+ setFocus(TRUE);
+
+ applyToSelection();
+}
+
+bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures)
+{
+ if (model.materials.size() > index)
+ {
+ const tinygltf::Material& material_in = model.materials[index];
+
+ if (set_textures)
+ {
+ S32 index;
+ LLUUID id;
+
+ // get base color texture
+ index = material_in.pbrMetallicRoughness.baseColorTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setBaseColorId(id);
+ }
+ else
+ {
+ setBaseColorId(LLUUID::null);
+ }
+
+ // get normal map
+ index = material_in.normalTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setNormalId(id);
+ }
+ else
+ {
+ setNormalId(LLUUID::null);
+ }
+
+ // get metallic-roughness texture
+ index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setMetallicRoughnessId(id);
+ }
+ else
+ {
+ setMetallicRoughnessId(LLUUID::null);
+ }
+
+ // get emissive texture
+ index = material_in.emissiveTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setEmissiveId(id);
+ }
+ else
+ {
+ setEmissiveId(LLUUID::null);
+ }
+ }
+
+ setAlphaMode(material_in.alphaMode);
+ setAlphaCutoff(material_in.alphaCutoff);
+
+ setBaseColor(LLTinyGLTFHelper::getColor(material_in.pbrMetallicRoughness.baseColorFactor));
+ setEmissiveColor(LLTinyGLTFHelper::getColor(material_in.emissiveFactor));
+
+ setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor);
+ setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor);
+
+ setDoubleSided(material_in.doubleSided);
+ }
+
+ return true;
+}
+
+/**
+ * Build a texture name from the contents of the (in tinyGLFT parlance)
+ * Image URI. This often is filepath to the original image on the users'
+ * local file system.
+ */
+const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, const std::string texture_type)
+{
+ // getBaseFileName() works differently on each platform and file patchs
+ // can contain both types of delimiter so unify them then extract the
+ // base name (no path or extension)
+ std::replace(image_uri.begin(), image_uri.end(), '\\', gDirUtilp->getDirDelimiter()[0]);
+ std::replace(image_uri.begin(), image_uri.end(), '/', gDirUtilp->getDirDelimiter()[0]);
+ const bool strip_extension = true;
+ std::string stripped_uri = gDirUtilp->getBaseFileName(image_uri, strip_extension);
+
+ // sometimes they can be really long and unwieldy - 64 chars is enough for anyone :)
+ const int max_texture_name_length = 64;
+ if (stripped_uri.length() > max_texture_name_length)
+ {
+ stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1);
+ }
+
+ // We intend to append the type of texture (base color, emissive etc.) to the
+ // name of the texture but sometimes the creator already did that. To try
+ // to avoid repeats (not perfect), we look for the texture type in the name
+ // and if we find it, do not append the type, later on. One way this fails
+ // (and it's fine for now) is I see some texture/image uris have a name like
+ // "metallic roughness" and of course, that doesn't match our predefined
+ // name "metallicroughness" - consider fix later..
+ bool name_includes_type = false;
+ std::string stripped_uri_lower = stripped_uri;
+ LLStringUtil::toLower(stripped_uri_lower);
+ stripped_uri_lower.erase(std::remove_if(stripped_uri_lower.begin(), stripped_uri_lower.end(), isspace), stripped_uri_lower.end());
+ std::string texture_type_lower = texture_type;
+ LLStringUtil::toLower(texture_type_lower);
+ texture_type_lower.erase(std::remove_if(texture_type_lower.begin(), texture_type_lower.end(), isspace), texture_type_lower.end());
+ if (stripped_uri_lower.find(texture_type_lower) != std::string::npos)
+ {
+ name_includes_type = true;
+ }
+
+ // uri doesn't include the type at all
+ if (name_includes_type == false)
+ {
+ // uri doesn't include the type and the uri is not empty
+ // so we can include everything
+ if (stripped_uri.length() > 0)
+ {
+ // example "DamagedHelmet: base layer"
+ return STRINGIZE(
+ mMaterialNameShort <<
+ ": " <<
+ stripped_uri <<
+ " (" <<
+ texture_type <<
+ ")"
+ );
+ }
+ else
+ // uri doesn't include the type (because the uri is empty)
+ // so we must reorganize the string a bit to include the name
+ // and an explicit name type
+ {
+ // example "DamagedHelmet: (Emissive)"
+ return STRINGIZE(
+ mMaterialNameShort <<
+ " (" <<
+ texture_type <<
+ ")"
+ );
+ }
+ }
+ else
+ // uri includes the type so just use it directly with the
+ // name of the material
+ {
+ return STRINGIZE(
+ // example: AlienBust: normal_layer
+ mMaterialNameShort <<
+ ": " <<
+ stripped_uri
+ );
+ }
+}
+
+/**
+ * Update the metadata for the material based on what we find in the loaded
+ * file (along with some assumptions and interpretations...). Fields include
+ * the name of the material, a material description and the names of the
+ * composite textures.
+ */
+void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index)
+{
+ // Use the name (without any path/extension) of the file that was
+ // uploaded as the base of the material name. Then if the name of the
+ // scene is present and not blank, append that and use the result as
+ // the name of the material. This is a first pass at creating a
+ // naming scheme that is useful to real content creators and hopefully
+ // avoid 500 materials in your inventory called "scene" or "Default"
+ const bool strip_extension = true;
+ std::string base_filename = gDirUtilp->getBaseFileName(filename, strip_extension);
+
+ // Extract the name of the scene. Note it is often blank or some very
+ // generic name like "Scene" or "Default" so using this in the name
+ // is less useful than you might imagine.
+ std::string material_name;
+ if (model.materials.size() > index && !model.materials[index].name.empty())
+ {
+ material_name = model.materials[index].name;
+ }
+ else if (model.scenes.size() > 0)
+ {
+ const tinygltf::Scene& scene_in = model.scenes[0];
+ if (scene_in.name.length())
+ {
+ material_name = scene_in.name;
+ }
+ else
+ {
+ // scene name is empty so no point using it
+ }
+ }
+ else
+ {
+ // scene name isn't present so no point using it
+ }
+
+ // If we have a valid material or scene name, use it to build the short and
+ // long versions of the material name. The long version is used
+ // as you might expect, for the material name. The short version is
+ // used as part of the image/texture name - the theory is that will
+ // allow content creators to track the material and the corresponding
+ // textures
+ if (material_name.length())
+ {
+ mMaterialNameShort = base_filename;
+
+ mMaterialName = STRINGIZE(
+ base_filename <<
+ " " <<
+ "(" <<
+ material_name <<
+ ")"
+ );
+ }
+ else
+ // otherwise, just use the trimmed filename as is
+ {
+ mMaterialNameShort = base_filename;
+ mMaterialName = base_filename;
+ }
+
+ // sanitize the material name so that it's compatible with the inventory
+ LLInventoryObject::correctInventoryName(mMaterialName);
+ LLInventoryObject::correctInventoryName(mMaterialNameShort);
+
+ // We also set the title of the floater to match the
+ // name of the material
+ setTitle(mMaterialName);
+
+ /**
+ * Extract / derive the names of each composite texture. For each, the
+ * index is used to to determine which of the "Images" is used. If the index
+ * is -1 then that texture type is not present in the material (Seems to be
+ * quite common that a material is missing 1 or more types of texture)
+ */
+ if (model.materials.size() > index)
+ {
+ const tinygltf::Material& first_material = model.materials[index];
+
+ mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME;
+ // note: unlike the other textures, base color doesn't have its own entry
+ // in the tinyGLTF Material struct. Rather, it is taken from a
+ // sub-texture in the pbrMetallicRoughness member
+ int index = first_material.pbrMetallicRoughness.baseColorTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ // sanitize the name we decide to use for each texture
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_BASE_COLOR_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mBaseColorName = texture_name;
+ }
+
+ mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME;
+ index = first_material.emissiveTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_EMISSIVE_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mEmissiveName = texture_name;
+ }
+
+ mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME;
+ index = first_material.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_METALLIC_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mMetallicRoughnessName = texture_name;
+ }
+
+ mNormalName = MATERIAL_NORMAL_DEFAULT_NAME;
+ index = first_material.normalTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_NORMAL_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mNormalName = texture_name;
+ }
+ }
+}
+
+void LLMaterialEditor::importMaterial()
+{
+ LLFilePickerReplyThread::startPicker(
+ [](const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)
+ {
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+ if (filenames.size() > 0)
+ {
+ LLMaterialEditor::loadMaterialFromFile(filenames[0], -1);
+ }
+ },
+ LLFilePicker::FFLOAD_MATERIAL,
+ true);
+}
+
+class LLRenderMaterialFunctor : public LLSelectedTEFunctor
+{
+public:
+ LLRenderMaterialFunctor(const LLUUID &id)
+ : mMatId(id)
+ {
+ }
+
+ bool apply(LLViewerObject* objectp, S32 te) override
+ {
+ if (objectp && objectp->permModify() && objectp->getVolume())
+ {
+ LLVOVolume* vobjp = (LLVOVolume*)objectp;
+ vobjp->setRenderMaterialID(te, mMatId, false /*preview only*/);
+ vobjp->updateTEMaterialTextures(te);
+ }
+ return true;
+ }
+private:
+ LLUUID mMatId;
+};
+
+class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor
+{
+public:
+ LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url)
+ : mEditor(me), mCapUrl(url)
+ {
+
+ }
+
+ bool apply(LLViewerObject* objectp, S32 te) override
+ {
+ // post override from given object and te to the simulator
+ // requestData should have:
+ // object_id - UUID of LLViewerObject
+ // side - S32 index of texture entry
+ // gltf_json - String of GLTF json for override data
+
+ if (objectp && objectp->permModify() && objectp->getVolume())
+ {
+ // Get material from object
+ // Selection can cover multiple objects, and live editor is
+ // supposed to overwrite changed values only
+ LLTextureEntry* tep = objectp->getTE(te);
+ LLPointer<LLGLTFMaterial> material = tep->getGLTFMaterial();
+ if (material.isNull())
+ {
+ material = new LLGLTFMaterial();
+ }
+
+ // Override object's values with values from editor where appropriate
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY)
+ {
+ material->mBaseColor = mEditor->getBaseColor();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_TRANSPARENCY_DIRTY)
+ {
+ material->mBaseColor.mV[3] = mEditor->getTransparency();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY)
+ {
+ material->mBaseColorId = mEditor->getBaseColorId();
+ }
+
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY)
+ {
+ material->mNormalId = mEditor->getNormalId();
+ }
+
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
+ {
+ material->mMetallicRoughnessId = mEditor->getMetallicRoughnessId();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
+ {
+ material->mMetallicFactor = mEditor->getMetalnessFactor();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY)
+ {
+ material->mRoughnessFactor = mEditor->getRoughnessFactor();
+ }
+
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY)
+ {
+ material->mEmissiveColor = mEditor->getEmissiveColor();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY)
+ {
+ material->mEmissiveId = mEditor->getEmissiveId();
+ }
+
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY)
+ {
+ material->mDoubleSided = mEditor->getDoubleSided();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY)
+ {
+ material->setAlphaMode(mEditor->getAlphaMode());
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY)
+ {
+ material->mAlphaCutoff = mEditor->getAlphaCutoff();
+ }
+
+ std::string overrides_json = material->asJSON();
+
+ LLSD overrides = llsd::map(
+ "object_id", objectp->getID(),
+ "side", te,
+ "gltf_json", overrides_json
+ );
+ LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides));
+ }
+ return true;
+ }
+
+private:
+ LLMaterialEditor * mEditor;
+ std::string mCapUrl;
+};
+
+void LLMaterialEditor::applyToSelection()
+{
+ if (!mIsOverride)
+ {
+ // Only apply if working with 'live' materials
+ // Might need a better way to distinguish 'live' mode.
+ // But only one live edit is supposed to work at a time
+ // as a pair to tools floater.
+ return;
+ }
+
+ std::string url = gAgent.getRegionCapability("ModifyMaterialParams");
+ if (!url.empty())
+ {
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ // TODO figure out how to get the right asset id in cases where we don't have a good one
+ LLRenderMaterialOverrideFunctor override_func(this, url);
+ selected_objects->applyToTEs(&override_func);
+ }
+ else
+ {
+ LL_WARNS() << "not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL;
+
+ // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere.
+ LLPointer<LLFetchedGLTFMaterial> mat = new LLFetchedGLTFMaterial();
+ getGLTFMaterial(mat);
+ static const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98");
+ gGLTFMaterialList.addMaterial(placeholder, mat);
+ LLRenderMaterialFunctor mat_func(placeholder);
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ selected_objects->applyToTEs(&mat_func);
+ }
+}
+
+void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat)
+{
+ mat->mBaseColor = getBaseColor();
+ mat->mBaseColor.mV[3] = getTransparency();
+ mat->mBaseColorId = getBaseColorId();
+
+ mat->mNormalId = getNormalId();
+
+ mat->mMetallicRoughnessId = getMetallicRoughnessId();
+ mat->mMetallicFactor = getMetalnessFactor();
+ mat->mRoughnessFactor = getRoughnessFactor();
+
+ mat->mEmissiveColor = getEmissiveColor();
+ mat->mEmissiveId = getEmissiveId();
+
+ mat->mDoubleSided = getDoubleSided();
+ mat->setAlphaMode(getAlphaMode());
+ mat->mAlphaCutoff = getAlphaCutoff();
+}
+
+void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat)
+{
+ setBaseColor(mat->mBaseColor);
+ setBaseColorId(mat->mBaseColorId);
+ setNormalId(mat->mNormalId);
+
+ setMetallicRoughnessId(mat->mMetallicRoughnessId);
+ setMetalnessFactor(mat->mMetallicFactor);
+ setRoughnessFactor(mat->mRoughnessFactor);
+
+ setEmissiveColor(mat->mEmissiveColor);
+ setEmissiveId(mat->mEmissiveId);
+
+ setDoubleSided(mat->mDoubleSided);
+ setAlphaMode(mat->getAlphaMode());
+ setAlphaCutoff(mat->mAlphaCutoff);
+}
+
+bool LLMaterialEditor::setFromSelection()
+{
+ struct LLSelectedTEGetGLTFRenderMaterial : public LLSelectedTEGetFunctor<LLPointer<LLGLTFMaterial> >
+ {
+ LLPointer<LLGLTFMaterial> get(LLViewerObject* objectp, S32 te_index)
+ {
+ if (!objectp)
+ {
+ return nullptr;
+ }
+ LLTextureEntry *tep = objectp->getTE(te_index);
+ if (!tep)
+ {
+ return nullptr;
+ }
+ return tep->getGLTFRenderMaterial(); // present user with combined override + asset
+ }
+ } func;
+
+ LLPointer<LLGLTFMaterial> mat;
+ bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat);
+ if (mat.notNull())
+ {
+ setFromGLTFMaterial(mat);
+ }
+ else
+ {
+ // pick defaults from a blank material;
+ LLGLTFMaterial blank_mat;
+ setFromGLTFMaterial(&blank_mat);
+ }
+
+ mBaseColorTextureCtrl->setTentative(!identical);
+ mMetallicTextureCtrl->setTentative(!identical);
+ mEmissiveTextureCtrl->setTentative(!identical);
+ mNormalTextureCtrl->setTentative(!identical);
+
+ return mat.notNull();
+}
+
+
+void LLMaterialEditor::loadAsset()
+{
+ // derived from LLPreviewNotecard::loadAsset
+
+ // TODO: see commented out "editor" references and make them do something appropriate to the UI
+
+ // request the asset.
+ const LLInventoryItem* item;
+ if (mNotecardInventoryID.notNull())
+ {
+ item = mAuxItem.get();
+ }
+ else
+ {
+ item = getItem();
+ }
+
+ bool fail = false;
+
+ if (item)
+ {
+ LLPermissions perm(item->getPermissions());
+ bool allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
+ bool allow_modify = canModify(mObjectUUID, item);
+ bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+
+ setCanSaveAs(allow_copy);
+ setMaterialName(item->getName());
+
+ {
+ mAssetID = item->getAssetUUID();
+ if (mAssetID.isNull())
+ {
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ loadDefaults();
+ resetUnsavedChanges();
+ setEnableEditing(allow_modify && !source_library);
+ }
+ else
+ {
+ LLHost source_sim = LLHost();
+ LLSD* user_data = new LLSD();
+
+ if (mNotecardInventoryID.notNull())
+ {
+ user_data->with("objectid", mNotecardObjectID).with("notecardid", mNotecardInventoryID);
+ }
+ else if (mObjectUUID.notNull())
+ {
+ LLViewerObject* objectp = gObjectList.findObject(mObjectUUID);
+ if (objectp && objectp->getRegion())
+ {
+ source_sim = objectp->getRegion()->getHost();
+ }
+ else
+ {
+ // The object that we're trying to look at disappeared, bail.
+ LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL;
+ mAssetID.setNull();
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ resetUnsavedChanges();
+ setEnableEditing(allow_modify && !source_library);
+ return;
+ }
+ user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID);
+ }
+ else
+ {
+ user_data = new LLSD(mItemUUID);
+ }
+
+ setEnableEditing(false); // wait for it to load
+
+ gAssetStorage->getInvItemAsset(source_sim,
+ gAgent.getID(),
+ gAgent.getSessionID(),
+ item->getPermissions().getOwner(),
+ mObjectUUID,
+ item->getUUID(),
+ item->getAssetUUID(),
+ item->getType(),
+ &onLoadComplete,
+ (void*)user_data,
+ TRUE);
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ }
+ }
+ }
+ else if (mObjectUUID.notNull() && mItemUUID.notNull())
+ {
+ LLViewerObject* objectp = gObjectList.findObject(mObjectUUID);
+ if (objectp && (objectp->isInventoryPending() || objectp->isInventoryDirty()))
+ {
+ // It's a material in object's inventory and we failed to get it because inventory is not up to date.
+ // Subscribe for callback and retry at inventoryChanged()
+ registerVOInventoryListener(objectp, NULL); //removes previous listener
+
+ if (objectp->isInventoryDirty())
+ {
+ objectp->requestInventory();
+ }
+ }
+ else
+ {
+ fail = true;
+ }
+ }
+ else
+ {
+ fail = true;
+ }
+
+ if (fail)
+ {
+ /*editor->setText(LLStringUtil::null);
+ editor->makePristine();
+ editor->setEnabled(TRUE);*/
+ // Don't set asset status here; we may not have set the item id yet
+ // (e.g. when this gets called initially)
+ //mAssetStatus = PREVIEW_ASSET_LOADED;
+ }
+}
+
+// static
+void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ void* user_data, S32 status, LLExtStat ext_status)
+{
+ LL_INFOS() << "LLMaterialEditor::onLoadComplete()" << LL_ENDL;
+ LLSD* floater_key = (LLSD*)user_data;
+ LLMaterialEditor* editor = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", *floater_key);
+ if (editor)
+ {
+ if (0 == status)
+ {
+ LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
+
+ S32 file_length = file.getSize();
+
+ std::vector<char> buffer(file_length + 1);
+ file.read((U8*)&buffer[0], file_length);
+
+ editor->decodeAsset(buffer);
+
+ BOOL allow_modify = editor->canModify(editor->mObjectUUID, editor->getItem());
+ BOOL source_library = editor->mObjectUUID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID());
+ editor->setEnableEditing(allow_modify && !source_library);
+ editor->resetUnsavedChanges();
+ editor->mAssetStatus = PREVIEW_ASSET_LOADED;
+ editor->setEnabled(true); // ready for use
+ }
+ else
+ {
+ if (LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
+ LL_ERR_FILE_EMPTY == status)
+ {
+ LLNotificationsUtil::add("MaterialMissing");
+ }
+ else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
+ {
+ LLNotificationsUtil::add("MaterialNoPermissions");
+ }
+ else
+ {
+ LLNotificationsUtil::add("UnableToLoadMaterial");
+ }
+ editor->setEnableEditing(false);
+
+ LL_WARNS() << "Problem loading material: " << status << LL_ENDL;
+ editor->mAssetStatus = PREVIEW_ASSET_ERROR;
+ }
+ }
+ delete floater_key;
+}
+
+void LLMaterialEditor::inventoryChanged(LLViewerObject* object,
+ LLInventoryObject::object_list_t* inventory,
+ S32 serial_num,
+ void* user_data)
+{
+ removeVOInventoryListener();
+ loadAsset();
+}
+
+
+void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id, upload_callback_f cb)
+{
+ if (asset_id.isNull()
+ || img == nullptr
+ || img->getDataSize() == 0)
+ {
+ return;
+ }
+
+ // copy image bytes into string
+ std::string buffer;
+ buffer.assign((const char*) img->getData(), img->getDataSize());
+
+ U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+
+
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLNewBufferedResourceUploadInfo>(
+ buffer,
+ asset_id,
+ name,
+ name,
+ 0,
+ LLFolderType::FT_TEXTURE,
+ LLInventoryType::IT_TEXTURE,
+ LLAssetType::AT_TEXTURE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost,
+ false,
+ cb));
+
+ upload_new_resource(uploadInfo);
+}
+
+S32 LLMaterialEditor::saveTextures()
+{
+ S32 work_count = 0;
+ LLSD key = getKey(); // must be locally declared for lambda's capture to work
+ if (mBaseColorTextureUploadId == getBaseColorId() && mBaseColorTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+ saveTexture(mBaseColorJ2C, mBaseColorName, mBaseColorTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setBaseColorId(newAssetId);
+ }
+ else
+ {
+ // To make sure that we won't retry (some failures can cb immediately)
+ me->setBaseColorId(LLUUID::null);
+ }
+ me->mUploadingTexturesCount--;
+
+ // try saving
+ me->saveIfNeeded();
+ }
+ });
+ }
+ if (mNormalTextureUploadId == getNormalId() && mNormalTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+ saveTexture(mNormalJ2C, mNormalName, mNormalTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setNormalId(newAssetId);
+ }
+ else
+ {
+ me->setNormalId(LLUUID::null);
+ }
+ me->setNormalId(newAssetId);
+ me->mUploadingTexturesCount--;
+
+ // try saving
+ me->saveIfNeeded();
+ }
+ });
+ }
+ if (mMetallicTextureUploadId == getMetallicRoughnessId() && mMetallicTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+ saveTexture(mMetallicRoughnessJ2C, mMetallicRoughnessName, mMetallicTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setMetallicRoughnessId(newAssetId);
+ }
+ else
+ {
+ me->setMetallicRoughnessId(LLUUID::null);
+ }
+ me->mUploadingTexturesCount--;
+
+ // try saving
+ me->saveIfNeeded();
+ }
+ });
+ }
+
+ if (mEmissiveTextureUploadId == getEmissiveId() && mEmissiveTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+ saveTexture(mEmissiveJ2C, mEmissiveName, mEmissiveTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(key));
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setEmissiveId(newAssetId);
+ }
+ else
+ {
+ me->setEmissiveId(LLUUID::null);
+ }
+ me->mUploadingTexturesCount--;
+
+ // try saving
+ me->saveIfNeeded();
+ }
+ });
+ }
+
+ // discard upload buffers once textures have been saved
+ clearTextures();
+
+ // asset storage can callback immediately, causing a decrease
+ // of mUploadingTexturesCount, report amount of work scheduled
+ // not amount of work remaining
+ return work_count;
+}
+
+void LLMaterialEditor::clearTextures()
+{
+ mBaseColorJ2C = nullptr;
+ mNormalJ2C = nullptr;
+ mEmissiveJ2C = nullptr;
+ mMetallicRoughnessJ2C = nullptr;
+
+ mBaseColorFetched = nullptr;
+ mNormalFetched = nullptr;
+ mMetallicRoughnessFetched = nullptr;
+ mEmissiveFetched = nullptr;
+
+ mBaseColorTextureUploadId.setNull();
+ mNormalTextureUploadId.setNull();
+ mMetallicTextureUploadId.setNull();
+ mEmissiveTextureUploadId.setNull();
+}
+
+void LLMaterialEditor::loadDefaults()
+{
+ tinygltf::Model model_in;
+ model_in.materials.resize(1);
+ setFromGltfModel(model_in, 0, true);
+}
+
+void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ httpOpts->setFollowRedirects(true);
+
+ LL_DEBUGS() << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL;
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Failed to modify material." << LL_ENDL;
+ }
+ else if (!result["success"].asBoolean())
+ {
+ LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL;
+ }
+}
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
new file mode 100644
index 0000000000..040dbe99da
--- /dev/null
+++ b/indra/newview/llmaterialeditor.h
@@ -0,0 +1,291 @@
+/**
+ * @file llmaterialeditor.h
+ * @brief LLMaterialEditor class header file
+ *
+ * $LicenseInfo:firstyear=2022&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$
+ */
+
+#pragma once
+
+#include "llpreview.h"
+#include "llvoinventorylistener.h"
+#include "llimagej2c.h"
+#include "llviewertexture.h"
+
+class LLTextureCtrl;
+class LLGLTFMaterial;
+class LLButton;
+class LLComboBox;
+class LLTextBox;
+
+namespace tinygltf
+{
+ class Model;
+}
+
+// todo: Consider making into a notification or just merging with
+// presets. Layout is identical to camera/graphics presets so there
+// is no point in having multiple separate xmls and classes.
+class LLFloaterComboOptions : public LLFloater
+{
+public:
+ typedef std::function<void(const std::string&, S32)> combo_callback;
+ LLFloaterComboOptions();
+
+ virtual ~LLFloaterComboOptions();
+ /*virtual*/ BOOL postBuild();
+
+ static LLFloaterComboOptions* showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::list<std::string> &options);
+
+ static LLFloaterComboOptions* showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::string &ok_text,
+ const std::string &cancel_text,
+ const std::list<std::string> &options);
+
+private:
+ void onConfirm();
+ void onCancel();
+
+protected:
+ combo_callback mCallback;
+
+ LLButton *mConfirmButton;
+ LLButton *mCancelButton;
+ LLComboBox *mComboOptions;
+ LLTextBox *mComboText;
+};
+
+class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
+{
+public:
+ LLMaterialEditor(const LLSD& key);
+
+ bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false);
+
+ void setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index);
+
+ // open a file dialog and select a gltf/glb file for import
+ static void importMaterial();
+
+ // for live preview, apply current material to currently selected object
+ void applyToSelection();
+
+ void getGLTFMaterial(LLGLTFMaterial* mat);
+
+ void loadAsset() override;
+ // @index if -1 and file contains more than one material,
+ // will promt to select specific one
+ static void loadMaterialFromFile(const std::string& filename, S32 index = -1);
+
+ void onSelectionChanged(); // // live overrides selection changes
+ void saveLiveValues(); // for restoration on cancel
+ static void loadLive();
+ static void loadObjectSave();
+
+ static void loadFromGLTFMaterial(LLUUID &asset_id);
+
+ static void onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status);
+
+ void inventoryChanged(LLViewerObject* object, LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data) override;
+
+ typedef std::function<void(LLUUID newAssetId, LLSD response)> upload_callback_f;
+ void saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id, upload_callback_f cb);
+
+ // save textures to inventory if needed
+ // returns amount of scheduled uploads
+ S32 saveTextures();
+ void clearTextures();
+
+ void onClickSave();
+
+ // get a dump of the json representation of the current state of the editor UI in GLTF format
+ std::string getGLTFJson(bool prettyprint = true);
+
+ void getGLBData(std::vector<U8>& data);
+
+ void getGLTFModel(tinygltf::Model& model);
+
+ std::string getEncodedAsset();
+
+ bool decodeAsset(const std::vector<char>& buffer);
+
+ bool saveIfNeeded();
+ static bool saveToInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id);
+
+ static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId);
+
+ static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
+
+ static void finishSaveAs(
+ const LLSD &oldKey,
+ const LLUUID &newItemId,
+ const std::string &buffer,
+ bool has_unsaved_changes);
+
+ void refreshFromInventory(const LLUUID& new_item_id = LLUUID::null);
+
+ void onClickSaveAs();
+ void onSaveAsMsgCallback(const LLSD& notification, const LLSD& response);
+ void onClickCancel();
+ void onCancelMsgCallback(const LLSD& notification, const LLSD& response);
+
+ // llpreview
+ void setObjectID(const LLUUID& object_id) override;
+ void setAuxItem(const LLInventoryItem* item) override;
+
+ // llpanel
+ BOOL postBuild() override;
+ void onClickCloseBtn(bool app_quitting = false) override;
+
+ void onClose(bool app_quitting) override;
+
+ LLUUID getBaseColorId();
+ void setBaseColorId(const LLUUID& id);
+ void setBaseColorUploadId(const LLUUID& id);
+
+ LLColor4 getBaseColor();
+
+ // sets both base color and transparency
+ void setBaseColor(const LLColor4& color);
+
+ F32 getTransparency();
+ void setTransparency(F32 transparency);
+
+ std::string getAlphaMode();
+ void setAlphaMode(const std::string& alpha_mode);
+
+ F32 getAlphaCutoff();
+ void setAlphaCutoff(F32 alpha_cutoff);
+
+ void setMaterialName(const std::string &name);
+
+ LLUUID getMetallicRoughnessId();
+ void setMetallicRoughnessId(const LLUUID& id);
+ void setMetallicRoughnessUploadId(const LLUUID& id);
+
+ F32 getMetalnessFactor();
+ void setMetalnessFactor(F32 factor);
+
+ F32 getRoughnessFactor();
+ void setRoughnessFactor(F32 factor);
+
+ LLUUID getEmissiveId();
+ void setEmissiveId(const LLUUID& id);
+ void setEmissiveUploadId(const LLUUID& id);
+
+ LLColor4 getEmissiveColor();
+ void setEmissiveColor(const LLColor4& color);
+
+ LLUUID getNormalId();
+ void setNormalId(const LLUUID& id);
+ void setNormalUploadId(const LLUUID& id);
+
+ bool getDoubleSided();
+ void setDoubleSided(bool double_sided);
+
+ void setCanSaveAs(bool value);
+ void setCanSave(bool value);
+ void setEnableEditing(bool can_modify);
+
+ void onCommitBaseColorTexture(LLUICtrl* ctrl, const LLSD& data);
+ void onCommitMetallicTexture(LLUICtrl* ctrl, const LLSD& data);
+ void onCommitEmissiveTexture(LLUICtrl* ctrl, const LLSD& data);
+ void onCommitNormalTexture(LLUICtrl* ctrl, const LLSD& data);
+
+ // initialize the UI from a default GLTF material
+ void loadDefaults();
+
+ void modifyMaterialCoro(std::string cap_url, LLSD overrides);
+
+ U32 getUnsavedChangesFlags() { return mUnsavedChanges; }
+
+private:
+ void setFromGLTFMaterial(LLGLTFMaterial* mat);
+ bool setFromSelection();
+
+ void loadMaterial(const tinygltf::Model &model, const std::string &filename_lc, S32 index);
+
+ friend class LLMaterialFilePicker;
+
+ LLUUID mAssetID;
+
+ LLTextureCtrl* mBaseColorTextureCtrl;
+ LLTextureCtrl* mMetallicTextureCtrl;
+ LLTextureCtrl* mEmissiveTextureCtrl;
+ LLTextureCtrl* mNormalTextureCtrl;
+
+ // 'Default' texture, unless it's null or from inventory is the one with the fee
+ LLUUID mBaseColorTextureUploadId;
+ LLUUID mMetallicTextureUploadId;
+ LLUUID mEmissiveTextureUploadId;
+ LLUUID mNormalTextureUploadId;
+
+ // last known name of each texture
+ std::string mBaseColorName;
+ std::string mNormalName;
+ std::string mMetallicRoughnessName;
+ std::string mEmissiveName;
+
+ // keep pointers to fetched textures or viewer will remove them
+ // if user temporary selects something else with 'apply now'
+ LLPointer<LLViewerFetchedTexture> mBaseColorFetched;
+ LLPointer<LLViewerFetchedTexture> mNormalFetched;
+ LLPointer<LLViewerFetchedTexture> mMetallicRoughnessFetched;
+ LLPointer<LLViewerFetchedTexture> mEmissiveFetched;
+
+ // J2C versions of packed buffers for uploading
+ LLPointer<LLImageJ2C> mBaseColorJ2C;
+ LLPointer<LLImageJ2C> mNormalJ2C;
+ LLPointer<LLImageJ2C> mMetallicRoughnessJ2C;
+ LLPointer<LLImageJ2C> mEmissiveJ2C;
+
+ // utility function for converting image uri into a texture name
+ const std::string getImageNameFromUri(std::string image_uri, const std::string texture_type);
+
+ // utility function for building a description of the imported material
+ // based on what we know about it.
+ const std::string buildMaterialDescription();
+
+ void resetUnsavedChanges();
+ void markChangesUnsaved(U32 dirty_flag);
+
+ U32 mUnsavedChanges; // flags to indicate individual changed parameters
+ S32 mUploadingTexturesCount;
+ S32 mExpectedUploadCost;
+ std::string mMaterialNameShort;
+ std::string mMaterialName;
+
+ // if true, this instance is live instance editing overrides
+ bool mIsOverride = false;
+ // local id, texture ids per face for object overrides
+ // for "cancel" support
+ std::map<U32, uuid_vec_t> mObjectOverridesSavedValues;
+ boost::signals2::connection mSelectionUpdateSlot;
+};
+
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 142977e939..d3b981e205 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -154,8 +154,7 @@ void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred)
if (matchPred(*it))
{
(*it)->markDead();
- // *TDOO: When C++11 is in change the following line to: it = c.erase(it);
- c.erase(it++);
+ it = c.erase(it);
}
else
{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 6fa71e130e..5a6010d5e4 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -383,6 +383,9 @@ U32 LLMeshRepository::sLODPending = 0;
U32 LLMeshRepository::sCacheBytesRead = 0;
U32 LLMeshRepository::sCacheBytesWritten = 0;
+U32 LLMeshRepository::sCacheBytesHeaders = 0;
+U32 LLMeshRepository::sCacheBytesSkins = 0;
+U32 LLMeshRepository::sCacheBytesDecomps = 0;
U32 LLMeshRepository::sCacheReads = 0;
U32 LLMeshRepository::sCacheWrites = 0;
U32 LLMeshRepository::sMaxLockHoldoffs = 0;
@@ -1874,6 +1877,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
LLMutexLock lock(mHeaderMutex);
mMeshHeaderSize[mesh_id] = header_size;
mMeshHeader[mesh_id] = header;
+ LLMeshRepository::sCacheBytesHeaders += header_size;
}
@@ -2051,17 +2055,6 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_
if (volume->unpackVolumeFaces(stream, data_size))
{
- //load volume faces into decomposition buffer
- S32 vertex_count = 0;
- S32 index_count = 0;
-
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
- vertex_count += face.mNumVertices;
- index_count += face.mNumIndices;
- }
-
d->mPhysicsShapeMesh.clear();
std::vector<LLVector3>& pos = d->mPhysicsShapeMesh.mPositions;
@@ -3013,27 +3006,6 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
return -1;
}
-void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
-{
- mThread->mMeshHeader[data.mUUID] = header;
-
- // we cache the mesh for default parameters
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH);
-
- for (U32 i = 0; i < 4; i++)
- {
- if (data.mModel[i].notNull())
- {
- LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
- volume->copyVolumeFaces(data.mModel[i]);
- volume->setMeshAssetLoaded(TRUE);
- }
- }
-
-}
-
// Handle failed or successful requests for mesh assets.
//
// Support for 200 responses was added for several reasons. One,
@@ -3951,6 +3923,8 @@ void LLMeshRepository::notifyLoadedMeshes()
void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)
{
mSkinMap[info.mMeshID] = info;
+ // Alternative: We can get skin size from header
+ sCacheBytesSkins += info.sizeBytes();
skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID);
if (iter != mLoadingSkins.end())
@@ -3974,10 +3948,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
{ //just insert decomp into map
mDecompositionMap[decomp->mMeshID] = decomp;
mLoadingDecompositions.erase(decomp->mMeshID);
+ sCacheBytesDecomps += decomp->sizeBytes();
}
else
{ //merge decomp with existing entry
+ sCacheBytesDecomps -= iter->second->sizeBytes();
iter->second->merge(decomp);
+ sCacheBytesDecomps += iter->second->sizeBytes();
+
mLoadingDecompositions.erase(decomp->mMeshID);
delete decomp;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 5459bbb4af..6fe4ea5514 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -552,6 +552,9 @@ public:
static U32 sLODProcessing;
static U32 sCacheBytesRead;
static U32 sCacheBytesWritten;
+ static U32 sCacheBytesHeaders;
+ static U32 sCacheBytesSkins;
+ static U32 sCacheBytesDecomps;
static U32 sCacheReads;
static U32 sCacheWrites;
static U32 sMaxLockHoldoffs; // Maximum sequential locking failures
@@ -641,8 +644,6 @@ public:
std::queue<LLUUID> mPendingPhysicsShapeRequests;
U32 mMeshThreadCount;
-
- void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header);
LLMeshRepoThread* mThread;
std::vector<LLMeshUploadThread*> mUploads;
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 859d987fc3..914528c7ce 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -30,6 +30,7 @@
#include "llmodelloader.h"
#include "lldaeloader.h"
+#include "llgltfloader.h"
#include "llfloatermodelpreview.h"
#include "llagent.h"
@@ -86,6 +87,7 @@ static const LLColor4 PREVIEW_DEG_FILL_COL(1.f, 0.f, 0.f, 0.5f);
static const F32 PREVIEW_DEG_EDGE_WIDTH(3.f);
static const F32 PREVIEW_DEG_POINT_SIZE(8.f);
static const F32 PREVIEW_ZOOM_LIMIT(10.f);
+static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape";
const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
@@ -432,6 +434,20 @@ void LLModelPreview::rebuildUploadData()
LLFloaterModelPreview::addStringToLog(out, false);
}
}
+ if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS))
+ {
+ // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition.
+ // That's ok, but might not what they wanted. Use default_physics_shape if found.
+ std::ostringstream out;
+ out << "No physics model specified for " << instance.mLabel;
+ if (mDefaultPhysicsShapeP)
+ {
+ out << " - using: " << DEFAULT_PHYSICS_MESH_NAME;
+ lod_model = mDefaultPhysicsShapeP;
+ }
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default.
+ }
if (lod_model)
{
@@ -732,20 +748,41 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
std::map<std::string, std::string> joint_alias_map;
getJointAliases(joint_alias_map);
- mModelLoader = new LLDAELoader(
- filename,
- lod,
- &LLModelPreview::loadedCallback,
- &LLModelPreview::lookupJointByName,
- &LLModelPreview::loadTextures,
- &LLModelPreview::stateChangedCallback,
- this,
- mJointTransformMap,
- mJointsFromNode,
- joint_alias_map,
- LLSkinningUtil::getMaxJointCount(),
- gSavedSettings.getU32("ImporterModelLimit"),
- gSavedSettings.getBOOL("ImporterPreprocessDAE"));
+ // three possible file extensions, .dae .gltf .glb
+ // check for .dae and if not then assume one of the .gl??
+ if (std::string::npos != filename.rfind(".dae"))
+ {
+ mModelLoader = new LLDAELoader(
+ filename,
+ lod,
+ &LLModelPreview::loadedCallback,
+ &LLModelPreview::lookupJointByName,
+ &LLModelPreview::loadTextures,
+ &LLModelPreview::stateChangedCallback,
+ this,
+ mJointTransformMap,
+ mJointsFromNode,
+ joint_alias_map,
+ LLSkinningUtil::getMaxJointCount(),
+ gSavedSettings.getU32("ImporterModelLimit"),
+ gSavedSettings.getBOOL("ImporterPreprocessDAE"));
+ }
+ else
+ {
+ mModelLoader = new LLGLTFLoader(
+ filename,
+ lod,
+ &LLModelPreview::loadedCallback,
+ &LLModelPreview::lookupJointByName,
+ &LLModelPreview::loadTextures,
+ &LLModelPreview::stateChangedCallback,
+ this,
+ mJointTransformMap,
+ mJointsFromNode,
+ joint_alias_map,
+ LLSkinningUtil::getMaxJointCount(),
+ gSavedSettings.getU32("ImporterModelLimit"));
+ }
if (force_disable_slm)
{
@@ -816,8 +853,10 @@ void LLModelPreview::clearIncompatible(S32 lod)
// at this point we don't care about sub-models,
// different amount of sub-models means face count mismatch, not incompatibility
U32 lod_size = countRootModels(mModel[lod]);
+ bool replaced_base_model = (lod == LLModel::LOD_HIGH);
for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
- { //clear out any entries that aren't compatible with this model
+ {
+ // Clear out any entries that aren't compatible with this model
if (i != lod)
{
if (countRootModels(mModel[i]) != lod_size)
@@ -831,9 +870,47 @@ void LLModelPreview::clearIncompatible(S32 lod)
mBaseModel = mModel[lod];
mBaseScene = mScene[lod];
mVertexBuffer[5].clear();
+ replaced_base_model = true;
+ }
+ }
+ }
+ }
+
+ if (replaced_base_model && !mGenLOD)
+ {
+ // In case base was replaced, we might need to restart generation
+
+ // Check if already started
+ bool subscribe_for_generation = mLodsQuery.empty();
+
+ // Remove previously scheduled work
+ mLodsQuery.clear();
+
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (!fmp) return;
+
+ // Schedule new work
+ for (S32 i = LLModel::LOD_HIGH; i >= 0; --i)
+ {
+ if (mModel[i].empty())
+ {
+ // Base model was replaced, regenerate this lod if applicable
+ LLComboBox* lod_combo = mFMP->findChild<LLComboBox>("lod_source_" + lod_name[i]);
+ if (!lod_combo) return;
+
+ S32 lod_mode = lod_combo->getCurrentIndex();
+ if (lod_mode != LOD_FROM_FILE)
+ {
+ mLodsQuery.push_back(i);
}
}
}
+
+ // Subscribe if we have pending work and not subscribed yet
+ if (!mLodsQuery.empty() && subscribe_for_generation)
+ {
+ doOnIdleRepeating(lodQueryCallback);
+ }
}
}
@@ -994,6 +1071,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
}
else
{
+ if (loaded_lod == LLModel::LOD_PHYSICS)
+ { // Explicitly loading physics. See if there is a default mesh.
+ LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own.
+ mDefaultPhysicsShapeP = nullptr;
+ FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform);
+ mWarnOfUnmatchedPhyicsMeshes = true;
+ }
BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
if (!legacyMatching)
{
@@ -1064,7 +1148,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
}
-
mModel[loaded_lod][idx]->mLabel = name;
}
}
@@ -1221,8 +1304,9 @@ void LLModelPreview::restoreNormals()
// Runs per object, but likely it is a better way to run per model+submodels
// returns a ratio of base model indices to resulting indices
// returns -1 in case of failure
-F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_decimator, F32 error_threshold, bool sloppy)
+F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_decimator, F32 error_threshold, eSimplificationMode simplification_mode)
{
+ // I. Weld faces together
// Figure out buffer size
S32 size_indices = 0;
S32 size_vertices = 0;
@@ -1245,7 +1329,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
// extra space for normals and text coords
S32 tc_bytes_size = ((size_vertices * sizeof(LLVector2)) + 0xF) & ~0xF;
- LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size);
+ LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size);
LLVector4a* combined_normals = combined_positions + size_vertices;
LLVector2* combined_tex_coords = (LLVector2*)(combined_normals + size_vertices);
@@ -1257,20 +1341,21 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
- // vertices
+ // Vertices
S32 copy_bytes = face.mNumVertices * sizeof(LLVector4a);
LLVector4a::memcpyNonAliased16((F32*)(combined_positions + combined_positions_shift), (F32*)face.mPositions, copy_bytes);
- // normals
+ // Normals
LLVector4a::memcpyNonAliased16((F32*)(combined_normals + combined_positions_shift), (F32*)face.mNormals, copy_bytes);
- // tex coords
+ // Tex coords
copy_bytes = face.mNumVertices * sizeof(LLVector2);
memcpy((void*)(combined_tex_coords + combined_positions_shift), (void*)face.mTexCoords, copy_bytes);
combined_positions_shift += face.mNumVertices;
- // indices, sadly can't do dumb memcpy for indices, need to adjust each value
+ // Indices
+ // Sadly can't do dumb memcpy for indices, need to adjust each value
for (S32 i = 0; i < face.mNumIndices; ++i)
{
U16 idx = face.mIndices[i];
@@ -1281,10 +1366,42 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
indices_idx_shift += face.mNumVertices;
}
- // Now that we have buffers, optimize
+ // II. Generate a shadow buffer if nessesary.
+ // Welds together vertices if possible
+
+ U32* shadow_indices = NULL;
+ // if MESH_OPTIMIZER_FULL, just leave as is, since generateShadowIndexBufferU32
+ // won't do anything new, model was remaped on a per face basis.
+ // Similar for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+ // since 'simplifySloppy' ignores all topology, including normals and uvs.
+ // Note: simplifySloppy can affect UVs significantly.
+ if (simplification_mode == MESH_OPTIMIZER_NO_NORMALS)
+ {
+ // strip normals, reflections should restore relatively correctly
+ shadow_indices = (U32*)ll_aligned_malloc_32(size_indices * sizeof(U32));
+ LLMeshOptimizer::generateShadowIndexBufferU32(shadow_indices, combined_indices, size_indices, combined_positions, NULL, combined_tex_coords, size_vertices);
+ }
+ if (simplification_mode == MESH_OPTIMIZER_NO_UVS)
+ {
+ // strip uvs, can heavily affect textures
+ shadow_indices = (U32*)ll_aligned_malloc_32(size_indices * sizeof(U32));
+ LLMeshOptimizer::generateShadowIndexBufferU32(shadow_indices, combined_indices, size_indices, combined_positions, NULL, NULL, size_vertices);
+ }
+
+ U32* source_indices = NULL;
+ if (shadow_indices)
+ {
+ source_indices = shadow_indices;
+ }
+ else
+ {
+ source_indices = combined_indices;
+ }
+
+ // III. Simplify
S32 target_indices = 0;
F32 result_error = 0; // how far from original the model is, 1 == 100%
- S32 new_indices = 0;
+ S32 size_new_indices = 0;
if (indices_decimator > 0)
{
@@ -1294,40 +1411,45 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
target_indices = 3;
}
- new_indices = LLMeshOptimizer::simplifyU32(
+
+ size_new_indices = LLMeshOptimizer::simplifyU32(
output_indices,
- combined_indices,
+ source_indices,
size_indices,
combined_positions,
size_vertices,
LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX],
target_indices,
error_threshold,
- sloppy,
+ simplification_mode == MESH_OPTIMIZER_NO_TOPOLOGY,
&result_error);
-
if (result_error < 0)
{
LL_WARNS() << "Negative result error from meshoptimizer for model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices << LL_ENDL;
}
- if (new_indices < 3)
+ // free unused buffers
+ ll_aligned_free_32(combined_indices);
+ ll_aligned_free_32(shadow_indices);
+ combined_indices = NULL;
+ shadow_indices = NULL;
+
+ if (size_new_indices < 3)
{
// Model should have at least one visible triangle
ll_aligned_free<64>(combined_positions);
ll_aligned_free_32(output_indices);
- ll_aligned_free_32(combined_indices);
return -1;
}
- // repack back into individual faces
+ // IV. Repack back into individual faces
- LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size);
+ LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size);
LLVector4a* buffer_normals = buffer_positions + size_vertices;
LLVector2* buffer_tex_coords = (LLVector2*)(buffer_normals + size_vertices);
S32 buffer_idx_size = (size_indices * sizeof(U16) + 0xF) & ~0xF;
@@ -1356,7 +1478,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
}
// Copy relevant indices and vertices
- for (S32 i = 0; i < new_indices; ++i)
+ for (S32 i = 0; i < size_new_indices; ++i)
{
U32 idx = output_indices[i];
@@ -1379,19 +1501,19 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
LL_WARNS() << "Over triangle limit. Failed to optimize in 'per object' mode, falling back to per face variant for"
<< " model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices
<< " error treshold: " << error_threshold
<< LL_ENDL;
// U16 vertices overflow shouldn't happen, but just in case
- new_indices = 0;
+ size_new_indices = 0;
valid_faces = 0;
for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
{
- genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, false);
+ genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, simplification_mode);
const LLVolumeFace &face = target_model->getVolumeFace(face_idx);
- new_indices += face.mNumIndices;
+ size_new_indices += face.mNumIndices;
if (face.mNumIndices >= 3)
{
valid_faces++;
@@ -1399,7 +1521,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
}
if (valid_faces)
{
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
else
{
@@ -1448,7 +1570,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
new_face.resizeIndices(buf_indices_copied);
new_face.resizeVertices(buf_positions_copied);
-
+ new_face.allocateTangents(buf_positions_copied);
S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size);
@@ -1469,18 +1591,17 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
ll_aligned_free<64>(buffer_positions);
ll_aligned_free_32(output_indices);
ll_aligned_free_16(buffer_indices);
- ll_aligned_free_32(combined_indices);
- if (new_indices < 3 || valid_faces == 0)
+ if (size_new_indices < 3 || valid_faces == 0)
{
// Model should have at least one visible triangle
return -1;
}
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
-F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_decimator, F32 error_threshold, bool sloppy)
+F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_decimator, F32 error_threshold, eSimplificationMode simplification_mode)
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
S32 size_indices = face.mNumIndices;
@@ -1488,14 +1609,40 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
{
return -1;
}
- // todo: do not allocate per each face, add one large buffer somewhere
- // faces have limited amount of indices
+
S32 size = (size_indices * sizeof(U16) + 0xF) & ~0xF;
- U16* output = (U16*)ll_aligned_malloc_16(size);
+ U16* output_indices = (U16*)ll_aligned_malloc_16(size);
+
+ U16* shadow_indices = NULL;
+ // if MESH_OPTIMIZER_FULL, just leave as is, since generateShadowIndexBufferU32
+ // won't do anything new, model was remaped on a per face basis.
+ // Similar for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+ // since 'simplifySloppy' ignores all topology, including normals and uvs.
+ if (simplification_mode == MESH_OPTIMIZER_NO_NORMALS)
+ {
+ U16* shadow_indices = (U16*)ll_aligned_malloc_16(size);
+ LLMeshOptimizer::generateShadowIndexBufferU16(shadow_indices, face.mIndices, size_indices, face.mPositions, NULL, face.mTexCoords, face.mNumVertices);
+ }
+ if (simplification_mode == MESH_OPTIMIZER_NO_UVS)
+ {
+ U16* shadow_indices = (U16*)ll_aligned_malloc_16(size);
+ LLMeshOptimizer::generateShadowIndexBufferU16(shadow_indices, face.mIndices, size_indices, face.mPositions, NULL, NULL, face.mNumVertices);
+ }
+ // Don't run ShadowIndexBuffer for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+
+ U16* source_indices = NULL;
+ if (shadow_indices)
+ {
+ source_indices = shadow_indices;
+ }
+ else
+ {
+ source_indices = face.mIndices;
+ }
S32 target_indices = 0;
F32 result_error = 0; // how far from original the model is, 1 == 100%
- S32 new_indices = 0;
+ S32 size_new_indices = 0;
if (indices_decimator > 0)
{
@@ -1505,25 +1652,25 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
{
target_indices = 3;
}
- new_indices = LLMeshOptimizer::simplify(
- output,
- face.mIndices,
+
+ size_new_indices = LLMeshOptimizer::simplify(
+ output_indices,
+ source_indices,
size_indices,
face.mPositions,
face.mNumVertices,
LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX],
target_indices,
error_threshold,
- sloppy,
+ simplification_mode == MESH_OPTIMIZER_NO_TOPOLOGY,
&result_error);
-
if (result_error < 0)
{
LL_WARNS() << "Negative result error from meshoptimizer for face " << face_idx
<< " of model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices
<< " error treshold: " << error_threshold
<< LL_ENDL;
@@ -1534,10 +1681,9 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
// Copy old values
new_face = face;
-
- if (new_indices < 3)
+ if (size_new_indices < 3)
{
- if (!sloppy)
+ if (simplification_mode != MESH_OPTIMIZER_NO_TOPOLOGY)
{
// meshopt_optimizeSloppy() can optimize triangles away even if target_indices is > 2,
// but optimize() isn't supposed to
@@ -1561,23 +1707,24 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
else
{
// Assign new values
- new_face.resizeIndices(new_indices); // will wipe out mIndices, so new_face can't substitute output
- S32 idx_size = (new_indices * sizeof(U16) + 0xF) & ~0xF;
- LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output, idx_size);
+ new_face.resizeIndices(size_new_indices); // will wipe out mIndices, so new_face can't substitute output
+ S32 idx_size = (size_new_indices * sizeof(U16) + 0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output_indices, idx_size);
- // clear unused values
+ // Clear unused values
new_face.optimize();
}
- ll_aligned_free_16(output);
+ ll_aligned_free_16(output_indices);
+ ll_aligned_free_16(shadow_indices);
- if (new_indices < 3)
+ if (size_new_indices < 3)
{
// At least one triangle is needed
return -1;
}
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 decimation, bool enforce_tri_limit)
@@ -1707,20 +1854,31 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
LLModel* target_model = mModel[lod][mdl_idx];
+ // carry over normalized transform into simplified model
+ for (int i = 0; i < base->getNumVolumeFaces(); ++i)
+ {
+ LLVolumeFace& src = base->getVolumeFace(i);
+ LLVolumeFace& dst = target_model->getVolumeFace(i);
+ dst.mNormalizedScale = src.mNormalizedScale;
+ }
+
S32 model_meshopt_mode = meshopt_mode;
// Ideally this should run not per model,
// but combine all submodels with origin model as well
- if (model_meshopt_mode == MESH_OPTIMIZER_COMBINE)
+ if (model_meshopt_mode == MESH_OPTIMIZER_PRECISE)
{
- // Run meshoptimizer for each model/object, up to 8 faces in one model.
-
- // Ideally this should run not per model,
- // but combine all submodels with origin model as well
- F32 res = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
- if (res < 0)
+ // Run meshoptimizer for each face
+ for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
{
- target_model->copyVolumeFaces(base);
+ F32 res = genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
+ if (res < 0)
+ {
+ // Mesh optimizer failed and returned an invalid model
+ const LLVolumeFace &face = base->getVolumeFace(face_idx);
+ LLVolumeFace &new_face = target_model->getVolumeFace(face_idx);
+ new_face = face;
+ }
}
}
@@ -1729,19 +1887,29 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// Run meshoptimizer for each face
for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
{
- if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, true) < 0)
+ if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY) < 0)
{
// Sloppy failed and returned an invalid model
- genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, false);
+ genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
}
}
}
if (model_meshopt_mode == MESH_OPTIMIZER_AUTO)
{
- // Switches between 'combine' method and 'sloppy' based on combine's result.
- F32 allowed_ratio_drift = 2.f;
- F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+ // Remove progressively more data if we can't reach the target.
+ F32 allowed_ratio_drift = 1.8f;
+ F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
+
+ if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
+ {
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_NORMALS);
+ }
+
+ if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
+ {
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_UVS);
+ }
if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
{
@@ -1749,10 +1917,11 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// Sloppy variant can fail entirely and has issues with precision,
// so code needs to do multiple attempts with different decimators.
// Todo: this is a bit of a mess, needs to be refined and improved
+
F32 last_working_decimator = 0.f;
F32 last_working_ratio = F32_MAX;
- F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+ F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
if (sloppy_ratio > 0)
{
@@ -1775,13 +1944,13 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// side due to overal lack of precision, and we don't need an ideal result, which
// likely does not exist, just a better one, so a partial correction is enough.
F32 sloppy_decimator = indices_decimator * (indices_decimator / sloppy_ratio + 1) / 2;
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
}
if (last_working_decimator > 0 && sloppy_ratio < last_working_ratio)
{
// Compensation didn't work, return back to previous decimator
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
}
if (sloppy_ratio < 0)
@@ -1814,7 +1983,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
&& sloppy_decimator > precise_ratio
&& sloppy_decimator > 1)// precise_ratio isn't supposed to be below 1, but check just in case
{
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
sloppy_decimator = sloppy_decimator / sloppy_decimation_step;
}
}
@@ -1834,7 +2003,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
else
{
// Fallback to normal method
- precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
}
LL_INFOS() << "Model " << target_model->getName()
@@ -2562,8 +2731,6 @@ void LLModelPreview::clearBuffers()
void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
{
- U32 tri_count = 0;
- U32 vertex_count = 0;
U32 mesh_count = 0;
@@ -2596,7 +2763,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
continue;
}
- LLModel* base_mdl = *base_iter;
base_iter++;
S32 num_faces = mdl->getNumVolumeFaces();
@@ -2671,7 +2837,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
//find closest weight to vf.mVertices[i].mPosition
LLVector3 pos(vf.mPositions[i].getF32ptr());
- const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
+ const LLModel::weight_list& weight_list = mdl->getJointInfluences(pos);
llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
LLVector4 w(0, 0, 0, 0);
@@ -2699,10 +2865,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
mVertexBuffer[lod][mdl].push_back(vb);
- vertex_count += num_vertices;
- tri_count += num_indices / 3;
++mesh_count;
-
}
}
}
@@ -2798,6 +2961,20 @@ void LLModelPreview::loadedCallback(
{
pPreview->lookupLODModelFiles(lod);
}
+
+ const LLVOAvatar* avatarp = pPreview->getPreviewAvatar();
+ if (avatarp) { // set up ground plane for possible rendering
+ const LLVector3 root_pos = avatarp->mRoot->getPosition();
+ const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents();
+ const LLVector4a min = ext[0], max = ext[1];
+ const F32 center = (max[2] - min[2]) * 0.5f;
+ const F32 ground = root_pos[2] - center;
+ auto plane = pPreview->mGroundPlane;
+ plane[0] = {min[0], min[1], ground};
+ plane[1] = {max[0], min[1], ground};
+ plane[2] = {max[0], max[1], ground};
+ plane[3] = {min[0], max[1], ground};
+ }
}
}
@@ -3005,6 +3182,9 @@ BOOL LLModelPreview::render()
// (note: all these UI updates need to be somewhere that is not render)
fmp->childSetValue("upload_skin", true);
mFirstSkinUpdate = false;
+ upload_skin = true;
+ skin_weight = true;
+ mViewOption["show_skin_weight"] = true;
}
fmp->enableViewOption("show_skin_weight");
@@ -3609,6 +3789,7 @@ BOOL LLModelPreview::render()
{
getPreviewAvatar()->renderBones();
}
+ renderGroundPlane(mPelvisZOffset);
if (shader)
{
shader->bind();
@@ -3630,6 +3811,28 @@ BOOL LLModelPreview::render()
return TRUE;
}
+void LLModelPreview::renderGroundPlane(float z_offset)
+{ // Not necesarilly general - beware - but it seems to meet the needs of LLModelPreview::render
+
+ gGL.diffuseColor3f( 1.0f, 0.0f, 1.0f );
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+ gGL.vertex3fv(mGroundPlane[1].mV);
+
+ gGL.vertex3fv(mGroundPlane[1].mV);
+ gGL.vertex3fv(mGroundPlane[2].mV);
+
+ gGL.vertex3fv(mGroundPlane[2].mV);
+ gGL.vertex3fv(mGroundPlane[3].mV);
+
+ gGL.vertex3fv(mGroundPlane[3].mV);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+
+ gGL.end();
+}
+
+
//-----------------------------------------------------------------------------
// refresh()
//-----------------------------------------------------------------------------
@@ -3745,7 +3948,7 @@ bool LLModelPreview::lodQueryCallback()
}
// return false to continue cycle
- return false;
+ return preview->mLodsQuery.empty();
}
}
// nothing to process
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
index 9e32215e6a..df7320768c 100644
--- a/indra/newview/llmodelpreview.h
+++ b/indra/newview/llmodelpreview.h
@@ -125,7 +125,7 @@ public:
{
LOD_FROM_FILE = 0,
MESH_OPTIMIZER_AUTO, // automatically selects method based on model or face
- MESH_OPTIMIZER_COMBINE, // combines faces into a single model, simplifies, then splits back into faces
+ MESH_OPTIMIZER_PRECISE, // combines faces into a single model, simplifies, then splits back into faces
MESH_OPTIMIZER_SLOPPY, // uses sloppy method, works per face
USE_LOD_ABOVE,
} eLoDMode;
@@ -224,14 +224,39 @@ private:
LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }
// Count amount of original models, excluding sub-models
static U32 countRootModels(LLModelLoader::model_list models);
+ LLVector3 mGroundPlane[4];
+ void renderGroundPlane(float z_offset = 0.0f);
+ /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh.
+ /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when
+ /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()).
+ ///
+ /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When
+ /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when
+ /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot.
+ /// When there are multiple meshes in each file, they are matched by name or order, and some meshes
+ /// are broken up by limitations into multiple objects, and thus there can be mismatches.)
+ bool mWarnOfUnmatchedPhyicsMeshes{false};
+ /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified.
+ /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME.
+ /// It is reset when such a name is not found, and when resetting the modelpreview.
+ /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true.
+ LLModel* mDefaultPhysicsShapeP{};
+
+ typedef enum
+ {
+ MESH_OPTIMIZER_FULL,
+ MESH_OPTIMIZER_NO_NORMALS,
+ MESH_OPTIMIZER_NO_UVS,
+ MESH_OPTIMIZER_NO_TOPOLOGY,
+ } eSimplificationMode;
// Merges faces into single mesh, simplifies using mesh optimizer,
// then splits back into faces.
// Returns reached simplification ratio. -1 in case of a failure.
- F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, bool sloppy);
+ F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, eSimplificationMode simplification_mode);
// Simplifies specified face using mesh optimizer.
// Returns reached simplification ratio. -1 in case of a failure.
- F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, bool sloppy);
+ F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, eSimplificationMode simplification_mode);
protected:
friend class LLModelLoader;
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 4a8ef53a8b..bf00d77dea 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -352,7 +352,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
void LLMuteList::updateAdd(const LLMute& mute)
{
- // External mutes (e.g. Avaline callers) are local only, don't send them to the server.
+ // External mutes are local only, don't send them to the server.
if (mute.mType == LLMute::EXTERNAL)
{
return;
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 5215126789..8058faa5c7 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -271,6 +271,25 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
return handled;
}
+// virtual
+BOOL LLNameListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
+ LLFloater* floater = gFloaterView->getParentFloater(this);
+ if (floater && floater->isFrontmost() && hit_item)
+ {
+ if(hit_item->isGroup())
+ {
+ ContextMenuType prev_menu = getContextMenuType();
+ setContextMenu(MENU_GROUP);
+ BOOL handled = LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+ setContextMenu(prev_menu);
+ return handled;
+ }
+ }
+ return LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+}
+
// public
void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos,
BOOL enabled)
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index ef0be135e6..5dd5da5892 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -170,6 +170,7 @@ public:
/*virtual*/ void updateColumns(bool force_update);
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
private:
void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false);
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item);
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 19dbbeb60e..f5ee1171d9 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -451,9 +451,9 @@ void LLNavigationBar::onLocationSelection()
if(value.has("AssetUUID"))
{
-
gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
- mSaveToLocationHistory = true;
+ // user teleported by manually inputting inventory landmark's name
+ mSaveToLocationHistory = false;
return;
}
else
@@ -713,7 +713,7 @@ void LLNavigationBar::resizeLayoutPanel()
}
void LLNavigationBar::invokeSearch(std::string search_text)
{
- LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text)));
+ LLFloaterReg::showInstance("search", LLSD().with("category", "standard").with("query", LLSD(search_text)));
}
void LLNavigationBar::clearHistoryCache()
@@ -733,3 +733,8 @@ int LLNavigationBar::getDefFavBarHeight()
{
return mDefaultFpRect.getHeight();
}
+
+bool LLNavigationBar::isRebakeNavMeshAvailable()
+{
+ return mCmbLocation->isNavMeshDirty();
+}
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 646911a62c..11c671294a 100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -102,6 +102,8 @@ public:
int getDefNavBarHeight();
int getDefFavBarHeight();
+
+ bool isRebakeNavMeshAvailable();
private:
// the distance between navigation panel and favorites panel in pixels
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 1240ce7c0f..b34be80b07 100644..100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -37,6 +37,7 @@
#include "llfocusmgr.h"
#include "lllocalcliprect.h"
#include "llrender.h"
+#include "llresmgr.h"
#include "llui.h"
#include "lltooltip.h"
@@ -47,11 +48,16 @@
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
#include "llcallingcard.h" // LLAvatarTracker
+#include "llfloaterland.h"
#include "llfloaterworldmap.h"
+#include "llparcel.h"
#include "lltracker.h"
#include "llsurface.h"
+#include "llurlmatch.h"
+#include "llurlregistry.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
+#include "llviewerparcelmgr.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h"
@@ -64,7 +70,10 @@
static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");
const F32 LLNetMap::MAP_SCALE_MIN = 32;
-const F32 LLNetMap::MAP_SCALE_MID = 1024;
+const F32 LLNetMap::MAP_SCALE_FAR = 32;
+const F32 LLNetMap::MAP_SCALE_MEDIUM = 128;
+const F32 LLNetMap::MAP_SCALE_CLOSE = 256;
+const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024;
const F32 LLNetMap::MAP_SCALE_MAX = 4096;
const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%)
@@ -78,13 +87,13 @@ const F64 COARSEUPDATE_MAX_Z = 1020.0f;
LLNetMap::LLNetMap (const Params & p)
: LLUICtrl (p),
mBackgroundColor (p.bg_color()),
- mScale( MAP_SCALE_MID ),
- mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ),
+ mScale( MAP_SCALE_MEDIUM ),
+ mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ),
mObjectMapTPM(0.f),
mObjectMapPixels(0.f),
- mTargetPan(0.f, 0.f),
mCurPan(0.f, 0.f),
mStartPan(0.f, 0.f),
+ mPopupWorldPos(0.f, 0.f, 0.f),
mMouseDown(0, 0),
mPanning(false),
mUpdateNow(false),
@@ -97,6 +106,13 @@ LLNetMap::LLNetMap (const Params & p)
mPopupMenu(NULL)
{
mScale = gSavedSettings.getF32("MiniMapScale");
+ if (gAgent.isFirstLogin())
+ {
+ // *HACK: On first run, set this to false for new users, otherwise the
+ // default is true to maintain consistent experience for existing
+ // users.
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
}
@@ -107,13 +123,22 @@ LLNetMap::~LLNetMap()
BOOL LLNetMap::postBuild()
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2));
- registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- return TRUE;
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar;
+
+ enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2));
+ commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2));
+ commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
+ commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2));
+ enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2));
+ commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2));
+ commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+ mPopupMenu->setItemEnabled("Re-center map", false);
+
+ return true;
}
void LLNetMap::setScale( F32 scale )
@@ -158,18 +183,32 @@ void LLNetMap::draw()
static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
- static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
+ static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f));
if (mObjectImagep.isNull())
{
createObjectImage();
}
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (auto_center)
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ bool auto_centering = auto_center && !mPanning;
+ mCentering = mCentering && !mPanning;
+
+ if (auto_centering || mCentering)
{
- mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));
+ mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f));
}
+ bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f;
+ if (centered)
+ {
+ mCurPan.mV[0] = 0.0f;
+ mCurPan.mV[1] = 0.0f;
+ mCentering = false;
+ }
+
+ bool can_recenter_map = !(centered || mCentering || auto_centering);
+ mPopupMenu->setItemEnabled("Re-center map", can_recenter_map);
+ updateAboutLandPopupButton();
// Prepare a scissor region
F32 rotation = 0;
@@ -216,7 +255,8 @@ void LLNetMap::draw()
}
// figure out where agent is
- S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const F32 scale_pixels_per_meter = mScale / region_width;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -225,8 +265,8 @@ void LLNetMap::draw()
// Find x and y position relative to camera's center.
LLVector3 origin_agent = regionp->getOriginAgent();
LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
- F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
- F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
+ F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter;
// background region rectangle
F32 bottom = relative_y;
@@ -249,6 +289,7 @@ void LLNetMap::draw()
}
+
// Draw using texture.
gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
gGL.begin(LLRender::QUADS);
@@ -310,8 +351,8 @@ void LLNetMap::draw()
LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
map_center_agent -= camera_position;
- map_center_agent.mV[VX] *= mScale/region_width;
- map_center_agent.mV[VY] *= mScale/region_width;
+ map_center_agent.mV[VX] *= scale_pixels_per_meter;
+ map_center_agent.mV[VY] *= scale_pixels_per_meter;
gGL.getTexUnit(0)->bind(mObjectImagep);
F32 image_half_width = 0.5f*mObjectMapPixels;
@@ -327,6 +368,13 @@ void LLNetMap::draw()
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
gGL.end();
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV);
+ }
gGL.popMatrix();
@@ -451,41 +499,34 @@ void LLNetMap::draw()
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
F32 far_clip_pixels = far_clip_meters * meters_to_pixels;
-
- F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
- F32 half_width_pixels = half_width_meters * meters_to_pixels;
- F32 ctr_x = (F32)center_sw_left;
- F32 ctr_y = (F32)center_sw_bottom;
-
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if( rotate_map )
- {
- gGL.color4fv((map_frustum_color()).mV);
-
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( ctr_x, ctr_y );
- gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
- gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
- gGL.end();
- }
- else
- {
- gGL.color4fv((map_frustum_rotating_color()).mV);
-
- // If we don't rotate the map, we have to rotate the frustum.
- gGL.pushMatrix();
- gGL.translatef( ctr_x, ctr_y, 0 );
- gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( 0, 0 );
- gGL.vertex2f( -half_width_pixels, far_clip_pixels );
- gGL.vertex2f( half_width_pixels, far_clip_pixels );
- gGL.end();
- gGL.popMatrix();
- }
+ F32 ctr_x = (F32)center_sw_left;
+ F32 ctr_y = (F32)center_sw_bottom;
+
+ const F32 steps_per_circle = 40.0f;
+ const F32 steps_per_radian = steps_per_circle / F_TWO_PI;
+ const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f));
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if( rotate_map )
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
+ else
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ // If we don't rotate the map, we have to rotate the frustum.
+ gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
}
gGL.popMatrix();
@@ -552,6 +593,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
}
}
+bool LLNetMap::isMouseOnPopupMenu()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return false;
+ }
+
+ S32 popup_x;
+ S32 popup_y;
+ LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y);
+ // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain
+ // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22
+ constexpr S32 tolerance = 10;
+ // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space.
+ // Assume the size of the popup menu is much larger than the provided tolerance.
+ // In practice, this is a [tolerance]px margin around the popup menu.
+ for (S32 sign_x = -1; sign_x <= 1; sign_x += 2)
+ {
+ for (S32 sign_y = -1; sign_y <= 1; sign_y += 2)
+ {
+ if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance)))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void LLNetMap::updateAboutLandPopupButton()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return;
+ }
+
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos);
+ if (!region)
+ {
+ mPopupMenu->setItemEnabled("About Land", false);
+ }
+ else
+ {
+ // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover
+ // parcel can be used to check if location-sensitive tooltip options are available.
+ if (isMouseOnPopupMenu())
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ bool valid_parcel = false;
+ if (hover_parcel)
+ {
+ valid_parcel = hover_parcel->getOwnerID().notNull();
+ }
+ mPopupMenu->setItemEnabled("About Land", valid_parcel);
+ }
+ }
+}
+
LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
{
x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]);
@@ -579,66 +679,152 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
- F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
+ // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
+ F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
F32 old_scale = mScale;
- setScale(new_scale);
+ setScale(new_scale);
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (!auto_center)
- {
- // Adjust pan to center the zoom on the mouse pointer
- LLVector2 zoom_offset;
- zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
- zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
- mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
- }
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ if (!auto_center)
+ {
+ // Adjust pan to center the zoom on the mouse pointer
+ LLVector2 zoom_offset;
+ zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
+ zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
+ mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
+ }
- return TRUE;
+ return true;
}
-BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask)
{
- if (gDisconnected)
- {
- return FALSE;
- }
+ if (gDisconnected)
+ {
+ return false;
+ }
- // If the cursor is near an avatar on the minimap, a mini-inspector will be
- // shown for the avatar, instead of the normal map tooltip.
- if (handleToolTipAgent(mClosestAgentToCursor))
- {
- return TRUE;
- }
+ // If the cursor is near an avatar on the minimap, a mini-inspector will be
+ // shown for the avatar, instead of the normal map tooltip.
+ if (handleToolTipAgent(mClosestAgentToCursor))
+ {
+ return true;
+ }
- LLRect sticky_rect;
- std::string region_name;
- LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
- if(region)
- {
- // set sticky_rect
- S32 SLOP = 4;
- localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
- sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
- sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
-
- region_name = region->getName();
- if (!region_name.empty())
- {
- region_name += "\n";
- }
- }
+ // The popup menu uses the hover parcel when it is open and the mouse is on
+ // top of it, with some additional tolerance. Returning early here prevents
+ // fighting over that hover parcel when getting tooltip info in the
+ // tolerance region.
+ if (isMouseOnPopupMenu())
+ {
+ return false;
+ }
- LLStringUtil::format_map_t args;
- args["[REGION]"] = region_name;
- std::string msg = mToolTipMsg;
- LLStringUtil::format(msg, args);
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(msg)
- .sticky_rect(sticky_rect));
-
- return TRUE;
+ LLRect sticky_rect;
+ S32 SLOP = 4;
+ localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
+ sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
+ sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
+
+ std::string parcel_name_msg;
+ std::string parcel_sale_price_msg;
+ std::string parcel_sale_area_msg;
+ std::string parcel_owner_msg;
+ std::string region_name_msg;
+
+ LLVector3d posGlobal = viewPosToGlobal(x, y);
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal);
+ if (region)
+ {
+ std::string region_name = region->getName();
+ if (!region_name.empty())
+ {
+ region_name_msg = mRegionNameMsg;
+ LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}});
+ }
+
+ // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is
+ // ambiguous.
+ if (gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ if (hover_parcel)
+ {
+ std::string parcel_name = hover_parcel->getName();
+ if (!parcel_name.empty())
+ {
+ parcel_name_msg = mParcelNameMsg;
+ LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}});
+ }
+
+ const LLUUID parcel_owner = hover_parcel->getOwnerID();
+ std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString();
+ static LLUrlMatch parcel_owner_name_url_match;
+ LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match);
+ if (!parcel_owner_name_url_match.empty())
+ {
+ parcel_owner_msg = mParcelOwnerMsg;
+ std::string parcel_owner_name = parcel_owner_name_url_match.getLabel();
+ LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}});
+ }
+
+ if (hover_parcel->getForSale())
+ {
+ const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID();
+ const LLUUID agent_id = gAgent.getID();
+ bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id;
+ if (show_for_sale)
+ {
+ S32 price = hover_parcel->getSalePrice();
+ S32 area = hover_parcel->getArea();
+ F32 cost_per_sqm = 0.0f;
+ if (area > 0)
+ {
+ cost_per_sqm = F32(price) / area;
+ }
+ std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price);
+ std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm);
+ parcel_sale_price_msg = mParcelSalePriceMsg;
+ LLStringUtil::format(parcel_sale_price_msg,
+ {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}});
+ std::string formatted_area = llformat("%d", area);
+ parcel_sale_area_msg = mParcelSaleAreaMsg;
+ LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}});
+ }
+ }
+ }
+ }
+ }
+
+ std::string tool_tip_hint_msg;
+ if (gSavedSettings.getBOOL("DoubleClickTeleport"))
+ {
+ tool_tip_hint_msg = mAltToolTipHintMsg;
+ }
+ else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
+ {
+ tool_tip_hint_msg = mToolTipHintMsg;
+ }
+
+ LLStringUtil::format_map_t args;
+ args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n';
+ args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n';
+ args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n';
+ args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n';
+ args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n';
+ args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n';
+
+ std::string msg = mToolTipMsg;
+ LLStringUtil::format(msg, args);
+ if (msg.back() == '\n')
+ {
+ msg.resize(msg.size() - 1);
+ }
+ LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect));
+
+ return true;
}
BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id)
@@ -811,59 +997,58 @@ void LLNetMap::createObjectImage()
mUpdateNow = true;
}
-BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (!(mask & MASK_SHIFT)) return FALSE;
-
- // Start panning
- gFocusMgr.setMouseCapture(this);
+ // Start panning
+ gFocusMgr.setMouseCapture(this);
- mStartPan = mCurPan;
- mMouseDown.mX = x;
- mMouseDown.mY = y;
- return TRUE;
+ mStartPan = mCurPan;
+ mMouseDown.mX = x;
+ mMouseDown.mY = y;
+ return true;
}
-BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask)
{
- if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3)
- handleClick(x,y,mask);
+ if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3)
+ {
+ handleClick(x, y, mask);
+ }
- if (hasMouseCapture())
- {
- if (mPanning)
- {
- // restore mouse cursor
- S32 local_x, local_y;
- local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
- local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
- LLRect clip_rect = getRect();
- clip_rect.stretch(-8);
- clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
- LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
-
- // finish the pan
- mPanning = false;
-
- mMouseDown.set(0, 0);
-
- // auto centre
- mTargetPan.setZero();
- }
- gViewerWindow->showCursor();
- gFocusMgr.setMouseCapture(NULL);
- return TRUE;
- }
- return FALSE;
+ if (hasMouseCapture())
+ {
+ if (mPanning)
+ {
+ // restore mouse cursor
+ S32 local_x, local_y;
+ local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
+ local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
+ LLRect clip_rect = getRect();
+ clip_rect.stretch(-8);
+ clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
+ LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
+
+ // finish the pan
+ mPanning = false;
+
+ mMouseDown.set(0, 0);
+ }
+ gViewerWindow->showCursor();
+ gFocusMgr.setMouseCapture(NULL);
+ return true;
+ }
+
+ return false;
}
BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (mPopupMenu)
{
+ mPopupWorldPos = viewPosToGlobal(x, y);
mPopupMenu->buildDrawLabels();
mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
+ mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0));
LLMenuGL::showPopup(this, mPopupMenu, x, y);
}
return TRUE;
@@ -911,6 +1096,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
+F32 LLNetMap::getScaleForName(std::string scale_name)
+{
+ if (scale_name == "very close")
+ {
+ return LLNetMap::MAP_SCALE_VERY_CLOSE;
+ }
+ else if (scale_name == "close")
+ {
+ return LLNetMap::MAP_SCALE_CLOSE;
+ }
+ else if (scale_name == "medium")
+ {
+ return LLNetMap::MAP_SCALE_MEDIUM;
+ }
+ else if (scale_name == "far")
+ {
+ return LLNetMap::MAP_SCALE_FAR;
+ }
+ return 0.0f;
+}
+
// static
bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )
{
@@ -928,7 +1134,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
{
if (!mPanning)
{
- // just started panning, so hide cursor
+ // Just started panning. Hide cursor.
mPanning = true;
gViewerWindow->hideCursor();
}
@@ -938,61 +1144,89 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
// Set pan to value at start of drag + offset
mCurPan += delta;
- mTargetPan = mCurPan;
gViewerWindow->moveCursorToCenter();
}
-
- // Doesn't really matter, cursor should be hidden
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- if (mask & MASK_SHIFT)
- {
- // If shift is held, change the cursor to hint that the map can be dragged
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- gViewerWindow->setCursor( UI_CURSOR_CROSS );
- }
}
+ if (mask & MASK_SHIFT)
+ {
+ // If shift is held, change the cursor to hint that the map can be
+ // dragged. However, holding shift is not required to drag the map.
+ gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
+ }
+ else
+ {
+ gViewerWindow->setCursor( UI_CURSOR_CROSS );
+ }
+
return TRUE;
}
-void LLNetMap::handleZoom(const LLSD& userdata)
+bool LLNetMap::isZoomChecked(const LLSD &userdata)
{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- setScale(scale);
- }
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ return scale == mScale;
+}
+
+void LLNetMap::setZoom(const LLSD &userdata)
+{
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ if (scale != 0.0f)
+ {
+ setScale(scale);
+ }
}
void LLNetMap::handleStopTracking (const LLSD& userdata)
{
if (mPopupMenu)
{
- mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ mPopupMenu->setItemEnabled ("Stop tracking", false);
LLTracker::stopTracking (LLTracker::isTracking(NULL));
}
}
+
+void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; }
+
+bool LLNetMap::isMapOrientationChecked(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate");
+ if (command_name == "north_at_top")
+ {
+ return !rotate_map;
+ }
+
+ if (command_name == "camera_at_top")
+ {
+ return rotate_map;
+ }
+
+ return false;
+}
+
+void LLNetMap::setMapOrientation(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ if (command_name == "north_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
+ else if (command_name == "camera_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", true);
+ }
+}
+
+void LLNetMap::popupShowAboutLand(const LLSD &userdata)
+{
+ // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection.
+ LLViewerParcelMgr::getInstance()->deselectLand();
+ LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos);
+ gMenuHolder->setParcelSelection(selection);
+
+ LLFloaterReg::showInstance("about_land", LLSD(), false);
+}
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 1f7e7d68c6..fe1aca65a9 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -62,9 +62,12 @@ protected:
public:
virtual ~LLNetMap();
- static const F32 MAP_SCALE_MIN;
- static const F32 MAP_SCALE_MID;
- static const F32 MAP_SCALE_MAX;
+ static const F32 MAP_SCALE_MIN;
+ static const F32 MAP_SCALE_FAR;
+ static const F32 MAP_SCALE_MEDIUM;
+ static const F32 MAP_SCALE_CLOSE;
+ static const F32 MAP_SCALE_VERY_CLOSE;
+ static const F32 MAP_SCALE_MAX;
/*virtual*/ void draw();
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
@@ -79,8 +82,17 @@ public:
/*virtual*/ BOOL handleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- void setScale( F32 scale );
- void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setScale(F32 scale);
+
+ void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; }
+ void setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; }
+ void setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; }
+ void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; }
+ void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; }
+ void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; }
+ void setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; }
+
void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
private:
@@ -94,11 +106,14 @@ private:
void drawTracking( const LLVector3d& pos_global,
const LLColor4& color,
BOOL draw_arrow = TRUE);
+ bool isMouseOnPopupMenu();
+ void updateAboutLandPopupButton();
BOOL handleToolTipAgent(const LLUUID& avatar_id);
static void showAvatarInspector(const LLUUID& avatar_id);
void createObjectImage();
+ F32 getScaleForName(std::string scale_name);
static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop);
private:
@@ -112,11 +127,12 @@ private:
F32 mObjectMapPixels; // Width of object map in pixels
F32 mDotRadius; // Size of avatar markers
- bool mPanning; // map is being dragged
- LLVector2 mTargetPan;
- LLVector2 mCurPan;
- LLVector2 mStartPan; // pan offset at start of drag
- LLCoordGL mMouseDown; // pointer position at start of drag
+ bool mPanning; // map is being dragged
+ bool mCentering; // map is being re-centered around the agent
+ LLVector2 mCurPan;
+ LLVector2 mStartPan; // pan offset at start of drag
+ LLVector3d mPopupWorldPos; // world position picked under mouse when context menu is opened
+ LLCoordGL mMouseDown; // pointer position at start of drag
LLVector3d mObjectImageCenterGlobal;
LLPointer<LLImageRaw> mObjectRawImagep;
@@ -125,14 +141,26 @@ private:
LLUUID mClosestAgentToCursor;
LLUUID mClosestAgentAtLastRightClick;
- std::string mToolTipMsg;
+ std::string mToolTipMsg;
+ std::string mParcelNameMsg;
+ std::string mParcelSalePriceMsg;
+ std::string mParcelSaleAreaMsg;
+ std::string mParcelOwnerMsg;
+ std::string mRegionNameMsg;
+ std::string mToolTipHintMsg;
+ std::string mAltToolTipHintMsg;
public:
void setSelected(uuid_vec_t uuids) { gmSelected=uuids; };
private:
- void handleZoom(const LLSD& userdata);
- void handleStopTracking (const LLSD& userdata);
+ bool isZoomChecked(const LLSD& userdata);
+ void setZoom(const LLSD& userdata);
+ void handleStopTracking(const LLSD& userdata);
+ void activateCenterMap(const LLSD& userdata);
+ bool isMapOrientationChecked(const LLSD& userdata);
+ void setMapOrientation(const LLSD& userdata);
+ void popupShowAboutLand(const LLSD& userdata);
LLMenuGL* mPopupMenu;
uuid_vec_t gmSelected;
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 4febb72c6c..d11b3b57f3 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1177,7 +1177,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
{
return;
}
- (new LLFilePickerReplyThread(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false);
}
void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id)
@@ -1374,6 +1374,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
texture_floaterp->setCanApply(false, true);
}
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 37ed4bc74c..ff33efe4aa 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.cpp
* @brief LLPanelAvatar and related class implementations
*
* $LicenseInfo:firstyear=2004&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$
*/
@@ -28,173 +28,127 @@
#include "llpanelavatar.h"
#include "llagent.h"
-#include "llavataractions.h"
-#include "llcallingcard.h"
-#include "llcombobox.h"
-#include "lldateutil.h" // ageFromDate()
-#include "llimview.h"
-#include "llmenubutton.h"
-#include "llnotificationsutil.h"
-#include "llslurl.h"
-#include "lltexteditor.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
+#include "llloadingindicator.h"
#include "lltooldraganddrop.h"
-#include "llscrollcontainer.h"
-#include "llavatariconctrl.h"
-#include "llfloaterreg.h"
-#include "llnotificationsutil.h"
-#include "llviewermenu.h" // is_agent_mappable
-#include "llvoiceclient.h"
-#include "lltextbox.h"
-#include "lltrans.h"
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLDropTarget
-//
-// This handy class is a simple way to drop something on another
-// view. It handles drop events, always setting itself to the size of
-// its parent.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLDropTarget : public LLView
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLView::Params>
- {
- Optional<LLUUID> agent_id;
- Params()
- : agent_id("agent_id")
- {
- changeDefault(mouse_opaque, false);
- changeDefault(follows.flags, FOLLOWS_ALL);
- }
- };
-
- LLDropTarget(const Params&);
- ~LLDropTarget();
-
- void doDrop(EDragAndDropType cargo_type, void* cargo_data);
-
- //
- // LLView functionality
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
-protected:
- LLUUID mAgentID;
-};
-
-LLDropTarget::LLDropTarget(const LLDropTarget::Params& p)
-: LLView(p),
- mAgentID(p.agent_id)
-{}
-LLDropTarget::~LLDropTarget()
+//////////////////////////////////////////////////////////////////////////
+// LLProfileDropTarget
+
+LLProfileDropTarget::LLProfileDropTarget(const LLProfileDropTarget::Params& p)
+: LLView(p),
+ mAgentID(p.agent_id)
{}
-void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
+void LLProfileDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
{
- LL_INFOS() << "LLDropTarget::doDrop()" << LL_ENDL;
+ LL_INFOS() << "LLProfileDropTarget::doDrop()" << LL_ENDL;
}
-BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
+BOOL LLProfileDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
{
- if(getParent())
- {
- LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
- cargo_type, cargo_data, accept);
+ if (getParent())
+ {
+ LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
+ cargo_type, cargo_data, accept);
- return TRUE;
- }
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
-static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target");
+static LLDefaultChildRegistry::Register<LLProfileDropTarget> r("profile_drop_target");
//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileTab
LLPanelProfileTab::LLPanelProfileTab()
: LLPanel()
, mAvatarId(LLUUID::null)
+, mLoadingState(PROFILE_INIT)
+, mSelfProfile(false)
{
}
LLPanelProfileTab::~LLPanelProfileTab()
{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
}
-void LLPanelProfileTab::setAvatarId(const LLUUID& id)
+void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id)
{
- if(id.notNull())
- {
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this);
- }
- mAvatarId = id;
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this);
- }
+ if (avatar_id.notNull())
+ {
+ mAvatarId = avatar_id;
+ mSelfProfile = (getAvatarId() == gAgentID);
+ }
}
void LLPanelProfileTab::onOpen(const LLSD& key)
{
- // Don't reset panel if we are opening it for same avatar.
- if(getAvatarId() != key.asUUID())
- {
- resetControls();
- resetData();
-
- scrollToTop();
- }
-
- // Update data even if we are viewing same avatar profile as some data might been changed.
- setAvatarId(key.asUUID());
- updateData();
- updateButtons();
+ // Update data even if we are viewing same avatar profile as some data might been changed.
+ setAvatarId(key.asUUID());
+
+ setApplyProgress(true);
+}
+
+void LLPanelProfileTab::setLoaded()
+{
+ setApplyProgress(false);
+
+ mLoadingState = PROFILE_LOADED;
+}
+
+void LLPanelProfileTab::setApplyProgress(bool started)
+{
+ LLLoadingIndicator* indicator = findChild<LLLoadingIndicator>("progress_indicator");
+
+ if (indicator)
+ {
+ indicator->setVisible(started);
+
+ if (started)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ }
+
+ LLView* panel = findChild<LLView>("indicator_stack");
+ if (panel)
+ {
+ panel->setVisible(started);
+ }
}
-void LLPanelProfileTab::scrollToTop()
+LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab()
+ : LLPanelProfileTab()
{
- LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
- if (scrollContainer)
- scrollContainer->goToTop();
}
-void LLPanelProfileTab::onMapButtonClick()
+LLPanelProfilePropertiesProcessorTab::~LLPanelProfilePropertiesProcessorTab()
{
- LLAvatarActions::showOnMap(getAvatarId());
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
}
-void LLPanelProfileTab::updateButtons()
+void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id)
{
- bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId());
-
- if(LLAvatarActions::isFriend(getAvatarId()))
- {
- getChildView("teleport")->setEnabled(is_buddy_online);
- }
- else
- {
- getChildView("teleport")->setEnabled(true);
- }
-
- bool enable_map_btn = (is_buddy_online &&
- is_agent_mappable(getAvatarId()))
- || gAgent.isGodlike();
- getChildView("show_on_map_btn")->setEnabled(enable_map_btn);
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+ }
}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index e33a850cfa..f182660c8e 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.h
- * @brief LLPanelAvatar and related class definitions
+ * @brief Legacy profile panel base class
*
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2019, 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$
*/
@@ -29,80 +29,141 @@
#include "llpanel.h"
#include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
-#include "llvoiceclient.h"
#include "llavatarnamecache.h"
class LLComboBox;
class LLLineEditor;
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLProfileDropTarget
+//
+// This handy class is a simple way to drop something on another
+// view. It handles drop events, always setting itself to the size of
+// its parent.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLProfileDropTarget : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<LLUUID> agent_id;
+ Params()
+ : agent_id("agent_id")
+ {
+ changeDefault(mouse_opaque, false);
+ changeDefault(follows.flags, FOLLOWS_ALL);
+ }
+ };
+
+ LLProfileDropTarget(const Params&);
+ ~LLProfileDropTarget() {}
+
+ void doDrop(EDragAndDropType cargo_type, void* cargo_data);
+
+ //
+ // LLView functionality
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
+
+protected:
+ LLUUID mAgentID;
+};
+
+
/**
* Base class for any Profile View.
*/
class LLPanelProfileTab
- : public LLPanel
- , public LLAvatarPropertiesObserver
+ : public LLPanel
{
public:
- /**
- * Sets avatar ID, sets panel as observer of avatar related info replies from server.
- */
- virtual void setAvatarId(const LLUUID& id);
-
- /**
- * Returns avatar ID.
- */
- virtual const LLUUID& getAvatarId() { return mAvatarId; }
-
- /**
- * Sends update data request to server.
- */
- virtual void updateData() = 0;
-
- /**
- * Clears panel data if viewing avatar info for first time and sends update data request.
- */
- virtual void onOpen(const LLSD& key);
-
- /**
- * Profile tabs should close any opened panels here.
- *
- * Called from LLPanelProfile::onOpen() before opening new profile.
- * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel
- * before new profile is displayed, otherwise new profile will
- * be hidden behind picture info panel.
- */
- virtual void onClosePanel() {}
-
- /**
- * Resets controls visibility, state, etc.
- */
- virtual void resetControls(){};
-
- /**
- * Clears all data received from server.
- */
- virtual void resetData(){};
-
- /*virtual*/ ~LLPanelProfileTab();
+ /**
+ * Sets avatar ID, sets panel as observer of avatar related info replies from server.
+ */
+ virtual void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Returns avatar ID.
+ */
+ virtual const LLUUID& getAvatarId() { return mAvatarId; }
+
+ /**
+ * Sends update data request to server.
+ */
+ virtual void updateData() {};
+
+ /**
+ * Clears panel data if viewing avatar info for first time and sends update data request.
+ */
+ virtual void onOpen(const LLSD& key);
+
+ /**
+ * Clears all data received from server.
+ */
+ virtual void resetData(){};
+
+ /*virtual*/ ~LLPanelProfileTab();
protected:
- LLPanelProfileTab();
+ LLPanelProfileTab();
+
+ enum ELoadingState
+ {
+ PROFILE_INIT,
+ PROFILE_LOADING,
+ PROFILE_LOADED,
+ };
+
+
+ // mLoading: false: Initial state, can request
+ // true: Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks)
+ // mLoaded: false: Initial state, show loading indicator
+ // true: Data recieved, which comes in a single message, hide indicator
+ ELoadingState getLoadingState() { return mLoadingState; }
+ virtual void setLoaded();
+ void setApplyProgress(bool started);
+
+ const bool getSelfProfile() const { return mSelfProfile; }
- /**
- * Scrolls panel to top when viewing avatar info for first time.
- */
- void scrollToTop();
+public:
+ void setIsLoading() { mLoadingState = PROFILE_LOADING; }
+ void resetLoading() { mLoadingState = PROFILE_INIT; }
- virtual void onMapButtonClick();
+ bool getStarted() { return mLoadingState != PROFILE_INIT; }
+ bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; }
- virtual void updateButtons();
+ virtual bool hasUnsavedChanges() { return false; }
+ virtual void commitUnsavedChanges() {}
private:
- LLUUID mAvatarId;
+ LLUUID mAvatarId;
+ ELoadingState mLoadingState;
+ bool mSelfProfile;
+};
+
+class LLPanelProfilePropertiesProcessorTab
+ : public LLPanelProfileTab
+ , public LLAvatarPropertiesObserver
+{
+public:
+ LLPanelProfilePropertiesProcessorTab();
+ ~LLPanelProfilePropertiesProcessorTab();
+
+ /*virtual*/ void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Processes data received from server via LLAvatarPropertiesObserver.
+ */
+ virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
};
#endif // LL_LLPANELAVATAR_H
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 3322e8a3df..3a4fc613b7 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -232,7 +232,7 @@ void LLPanelBlockedList::onFilterEdit(const std::string& search_string)
void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
{
if (names.empty() || ids.empty()) return;
- LLMute mute(ids[0], names[0].getAccountName(), LLMute::AGENT);
+ LLMute mute(ids[0], names[0].getUserName(), LLMute::AGENT);
LLMuteList::getInstance()->add(mute);
showPanelAndSelect(mute.mID);
}
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index c0342eef4e..183000ceac 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.cpp
- * @brief LLPanelClassified class implementation
+ * @brief LLPanelClassifiedInfo class implementation
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -34,33 +34,21 @@
#include "lldispatcher.h"
#include "llfloaterreg.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
#include "llparcel.h"
#include "llagent.h"
#include "llclassifiedflags.h"
-#include "llcommandhandler.h" // for classified HTML detail page click tracking
#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llcombobox.h"
#include "lltexturectrl.h"
-#include "lltexteditor.h"
-#include "llviewerparcelmgr.h"
#include "llfloaterworldmap.h"
#include "llviewergenericmessage.h" // send_generic_message
#include "llviewerregion.h"
-#include "llviewertexture.h"
-#include "lltrans.h"
#include "llscrollcontainer.h"
-#include "llstatusbar.h"
-#include "llviewertexture.h"
#include "llcorehttputil.h"
-const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
-
//static
LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels;
+static LLPanelInjector<LLPanelClassifiedInfo> t_panel_panel_classified_info("panel_classified_info");
// "classifiedclickthrough"
// strings[0] = classified_id
@@ -118,17 +106,8 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
sAllPanels.remove(this);
}
-// static
-LLPanelClassifiedInfo* LLPanelClassifiedInfo::create()
-{
- LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo();
- panel->buildFromFile("panel_classified_info.xml");
- return panel;
-}
-
BOOL LLPanelClassifiedInfo::postBuild()
{
- childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this));
childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this));
childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this));
@@ -144,16 +123,6 @@ BOOL LLPanelClassifiedInfo::postBuild()
return TRUE;
}
-void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("edit_btn")->setClickedCallback(cb);
-}
-
void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
{
LLPanel::reshape(width, height, called_from_parent);
@@ -286,6 +255,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t
getChild<LLUICtrl>("creation_date")->setValue(date_str);
setInfoLoaded(true);
+
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
}
}
@@ -590,588 +561,4 @@ void LLPanelClassifiedInfo::onTeleportClick()
}
}
-void LLPanelClassifiedInfo::onExit()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
- gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-static const S32 CB_ITEM_MATURE = 0;
-static const S32 CB_ITEM_PG = 1;
-
-LLPanelClassifiedEdit::LLPanelClassifiedEdit()
- : LLPanelClassifiedInfo()
- , mIsNew(false)
- , mIsNewWithErrors(false)
- , mCanClose(false)
- , mPublishFloater(NULL)
-{
-}
-
-LLPanelClassifiedEdit::~LLPanelClassifiedEdit()
-{
-}
-
-//static
-LLPanelClassifiedEdit* LLPanelClassifiedEdit::create()
-{
- LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit();
- panel->buildFromFile("panel_edit_classified.xml");
- return panel;
-}
-
-BOOL LLPanelClassifiedEdit::postBuild()
-{
- LLPanelClassifiedInfo::postBuild();
-
- LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon");
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
- edit_icon->setVisible(false);
-
- LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- LLComboBox* combobox = getChild<LLComboBox>( "category");
- LLClassifiedInfo::cat_map::iterator iter;
- for (iter = LLClassifiedInfo::sCategories.begin();
- iter != LLClassifiedInfo::sCategories.end();
- iter++)
- {
- combobox->add(LLTrans::getString(iter->second));
- }
-
- combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this));
-
- mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this));
-
- return TRUE;
-}
-
-void LLPanelClassifiedEdit::fillIn(const LLSD& key)
-{
- setAvatarId(gAgent.getID());
-
- if(key.isUndefined())
- {
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID snapshot_id = LLUUID::null;
- std::string desc;
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- if(parcel)
- {
- desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- getChild<LLUICtrl>("classified_name")->setValue(makeClassifiedName());
- getChild<LLUICtrl>("classified_desc")->setValue(desc);
- setSnapshotId(snapshot_id);
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
- // server will set valid parcel id
- setParcelId(LLUUID::null);
- }
- else
- {
- setClassifiedId(key["classified_id"]);
- setClassifiedName(key["name"]);
- setDescription(key["desc"]);
- setSnapshotId(key["snapshot_id"]);
- setCategory((U32)key["category"].asInteger());
- setContentType((U32)key["content_type"].asInteger());
- setClassifiedLocation(key["location_text"]);
- getChild<LLUICtrl>("auto_renew")->setValue(key["auto_renew"]);
- getChild<LLUICtrl>("price_for_listing")->setValue(key["price_for_listing"].asInteger());
- }
-}
-
-void LLPanelClassifiedEdit::onOpen(const LLSD& key)
-{
- mIsNew = key.isUndefined();
-
- scrollToTop();
-
- // classified is not created yet
- bool is_new = isNew() || isNewWithErrors();
-
- if(is_new)
- {
- resetData();
- resetControls();
-
- fillIn(key);
-
- if(isNew())
- {
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- }
- }
- else
- {
- LLPanelClassifiedInfo::onOpen(key);
- }
-
- std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label");
- getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", save_btn_label);
-
- enableVerbs(is_new);
- enableEditing(is_new);
- showEditing(!is_new);
- resetDirty();
- setInfoLoaded(false);
-}
-
-void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO == type)
- {
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if(c_info && getClassifiedId() == c_info->classified_id)
- {
- // see LLPanelClassifiedEdit::sendUpdate() for notes
- mIsNewWithErrors = false;
- // for just created classified - panel will probably be closed when we get here.
- if(!getVisible())
- {
- return;
- }
-
- enableEditing(true);
-
- setClassifiedName(c_info->name);
- setDescription(c_info->description);
- setSnapshotId(c_info->snapshot_id);
- setParcelId(c_info->parcel_id);
- setPosGlobal(c_info->pos_global);
-
- setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
- // *HACK see LLPanelClassifiedEdit::sendUpdate()
- setCategory(c_info->category - 1);
-
- bool mature = is_cf_mature(c_info->flags);
- bool auto_renew = is_cf_auto_renew(c_info->flags);
-
- setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
- getChild<LLUICtrl>("auto_renew")->setValue(auto_renew);
- getChild<LLUICtrl>("price_for_listing")->setValue(c_info->price_for_listing);
- getChildView("price_for_listing")->setEnabled(isNew());
-
- resetDirty();
- setInfoLoaded(true);
- enableVerbs(false);
-
- // for just created classified - in case user opened edit panel before processProperties() callback
- getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label"));
- }
- }
-}
-
-BOOL LLPanelClassifiedEdit::isDirty() const
-{
- if(mIsNew)
- {
- return TRUE;
- }
-
- BOOL dirty = false;
-
- dirty |= LLPanelClassifiedInfo::isDirty();
- dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty();
- dirty |= getChild<LLUICtrl>("classified_name")->isDirty();
- dirty |= getChild<LLUICtrl>("classified_desc")->isDirty();
- dirty |= getChild<LLUICtrl>("category")->isDirty();
- dirty |= getChild<LLUICtrl>("content_type")->isDirty();
- dirty |= getChild<LLUICtrl>("auto_renew")->isDirty();
- dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty();
-
- return dirty;
-}
-
-void LLPanelClassifiedEdit::resetDirty()
-{
- LLPanelClassifiedInfo::resetDirty();
- getChild<LLUICtrl>("classified_snapshot")->resetDirty();
- getChild<LLUICtrl>("classified_name")->resetDirty();
-
- LLTextEditor* desc = getChild<LLTextEditor>("classified_desc");
- // call blockUndo() to really reset dirty(and make isDirty work as intended)
- desc->blockUndo();
- desc->resetDirty();
-
- getChild<LLUICtrl>("category")->resetDirty();
- getChild<LLUICtrl>("content_type")->resetDirty();
- getChild<LLUICtrl>("auto_renew")->resetDirty();
- getChild<LLUICtrl>("price_for_listing")->resetDirty();
-}
-
-void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb)
-{
- mSaveButtonClickedSignal.connect(cb);
-}
-
-void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedEdit::resetControls()
-{
- LLPanelClassifiedInfo::resetControls();
-
- getChild<LLComboBox>("category")->setCurrentByIndex(0);
- getChild<LLComboBox>("content_type")->setCurrentByIndex(0);
- getChild<LLUICtrl>("auto_renew")->setValue(false);
- getChild<LLUICtrl>("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING);
- getChildView("price_for_listing")->setEnabled(TRUE);
-}
-
-bool LLPanelClassifiedEdit::canClose()
-{
- return mCanClose;
-}
-
-void LLPanelClassifiedEdit::draw()
-{
- LLPanel::draw();
-
- // Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback
- // does not trigger callbacks when user navigates through images.
- stretchSnapshot();
-}
-
-void LLPanelClassifiedEdit::stretchSnapshot()
-{
- LLPanelClassifiedInfo::stretchSnapshot();
-
- getChild<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect());
-}
-
-U32 LLPanelClassifiedEdit::getContentType()
-{
- LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
- return ct_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setContentType(U32 content_type)
-{
- LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
- ct_cb->setCurrentByIndex(content_type);
- ct_cb->resetDirty();
-}
-
-bool LLPanelClassifiedEdit::getAutoRenew()
-{
- return getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
-}
-
-void LLPanelClassifiedEdit::sendUpdate()
-{
- LLAvatarClassifiedInfo c_data;
-
- if(getClassifiedId().isNull())
- {
- setClassifiedId(LLUUID::generateNewID());
- }
-
- c_data.agent_id = gAgent.getID();
- c_data.classified_id = getClassifiedId();
- // *HACK
- // Categories on server start with 1 while combo-box index starts with 0
- c_data.category = getCategory() + 1;
- c_data.name = getClassifiedName();
- c_data.description = getDescription();
- c_data.parcel_id = getParcelId();
- c_data.snapshot_id = getSnapshotId();
- c_data.pos_global = getPosGlobal();
- c_data.flags = getFlags();
- c_data.price_for_listing = getPriceForListing();
-
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
-
- if(isNew())
- {
- // Lets assume there will be some error.
- // Successful sendClassifiedInfoUpdate will trigger processProperties and
- // let us know there was no error.
- mIsNewWithErrors = true;
- }
-}
-
-U32 LLPanelClassifiedEdit::getCategory()
-{
- LLComboBox* cat_cb = getChild<LLComboBox>("category");
- return cat_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setCategory(U32 category)
-{
- LLComboBox* cat_cb = getChild<LLComboBox>("category");
- cat_cb->setCurrentByIndex(category);
- cat_cb->resetDirty();
-}
-
-U8 LLPanelClassifiedEdit::getFlags()
-{
- bool auto_renew = getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
-
- LLComboBox* content_cb = getChild<LLComboBox>("content_type");
- bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE;
-
- return pack_classified_flags_request(auto_renew, false, mature, false);
-}
-
-void LLPanelClassifiedEdit::enableVerbs(bool enable)
-{
- getChildView("save_changes_btn")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::enableEditing(bool enable)
-{
- getChildView("classified_snapshot")->setEnabled(enable);
- getChildView("classified_name")->setEnabled(enable);
- getChildView("classified_desc")->setEnabled(enable);
- getChildView("set_to_curr_location_btn")->setEnabled(enable);
- getChildView("category")->setEnabled(enable);
- getChildView("content_type")->setEnabled(enable);
- getChildView("price_for_listing")->setEnabled(enable);
- getChildView("auto_renew")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::showEditing(bool show)
-{
- getChildView("price_for_listing_label")->setVisible( show);
- getChildView("price_for_listing")->setVisible( show);
-}
-
-std::string LLPanelClassifiedEdit::makeClassifiedName()
-{
- std::string name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- name = parcel->getName();
- }
-
- if(!name.empty())
- {
- return name;
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- name = region->getName();
- }
-
- return name;
-}
-
-S32 LLPanelClassifiedEdit::getPriceForListing()
-{
- return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPanelClassifiedEdit::setPriceForListing(S32 price)
-{
- getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-void LLPanelClassifiedEdit::onSetLocationClick()
-{
- setPosGlobal(gAgent.getPositionGlobal());
- setParcelId(LLUUID::null);
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
-
- // mark classified as dirty
- setValue(LLSD());
-
- onChange();
-}
-
-void LLPanelClassifiedEdit::onChange()
-{
- enableVerbs(isDirty());
-}
-
-void LLPanelClassifiedEdit::onSaveClick()
-{
- mCanClose = false;
-
- if(!isValidName())
- {
- notifyInvalidName();
- return;
- }
- if(isNew() || isNewWithErrors())
- {
- if(gStatusBar->getBalance() < getPriceForListing())
- {
- LLNotificationsUtil::add("ClassifiedInsufficientFunds");
- return;
- }
-
- mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
- "publish_classified", LLSD());
-
- if(!mPublishFloater)
- {
- mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
- "publish_classified", LLSD());
-
- mPublishFloater->setPublishClickedCallback(boost::bind
- (&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this));
- }
-
- // set spinner value before it has focus or value wont be set
- mPublishFloater->setPrice(getPriceForListing());
- mPublishFloater->openFloater(mPublishFloater->getKey());
- mPublishFloater->center();
- }
- else
- {
- doSave();
- }
-}
-
-void LLPanelClassifiedEdit::doSave()
-{
- mCanClose = true;
- sendUpdate();
- resetDirty();
-
- mSaveButtonClickedSignal(this, LLSD());
-}
-
-void LLPanelClassifiedEdit::onPublishFloaterPublishClicked()
-{
- setPriceForListing(mPublishFloater->getPrice());
-
- doSave();
-}
-
-std::string LLPanelClassifiedEdit::getLocationNotice()
-{
- static std::string location_notice = getString("location_notice");
- return location_notice;
-}
-
-bool LLPanelClassifiedEdit::isValidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- return false;
- }
- if (!isalnum(name[0]))
- {
- return false;
- }
-
- return true;
-}
-
-void LLPanelClassifiedEdit::notifyInvalidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- LLNotificationsUtil::add("BlankClassifiedName");
- }
- else if (!isalnum(name[0]))
- {
- LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
- }
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- ctrl->setVisible(TRUE);
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- ctrl->setVisible(FALSE);
-}
-
-void LLPanelClassifiedEdit::onTextureSelected()
-{
- setSnapshotId(mSnapshotCtrl->getValue().asUUID());
- onChange();
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
- : LLFloater(key)
-{
-}
-
-LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
-{
-}
-
-BOOL LLPublishClassifiedFloater::postBuild()
-{
- LLFloater::postBuild();
-
- childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
- childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
-
- return TRUE;
-}
-
-void LLPublishClassifiedFloater::setPrice(S32 price)
-{
- getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-S32 LLPublishClassifiedFloater::getPrice()
-{
- return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("publish_btn")->setClickedCallback(cb);
-}
-
-void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
//EOF
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index b292782615..471becd0f7 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.h
- * @brief LLPanelClassified class definition
+ * @brief LLPanelClassifiedInfo class definition
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -35,39 +35,16 @@
#include "llfloater.h"
#include "llpanel.h"
#include "llrect.h"
-#include "lluuid.h"
-#include "v3dmath.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
class LLScrollContainer;
class LLTextureCtrl;
-class LLUICtrl;
-
-class LLPublishClassifiedFloater : public LLFloater
-{
-public:
- LLPublishClassifiedFloater(const LLSD& key);
- virtual ~LLPublishClassifiedFloater();
-
- /*virtual*/ BOOL postBuild();
-
- void setPrice(S32 price);
- S32 getPrice();
-
- void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
- void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
-
-private:
-};
class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
{
LOG_CLASS(LLPanelClassifiedInfo);
public:
- static LLPanelClassifiedInfo* create();
-
+ LLPanelClassifiedInfo();
virtual ~LLPanelClassifiedInfo();
/*virtual*/ void onOpen(const LLSD& key);
@@ -135,18 +112,12 @@ public:
const LLVector3d& global_pos,
const std::string& sim_name);
- void setExitCallback(const commit_callback_t& cb);
-
- void setEditClassifiedCallback(const commit_callback_t& cb);
-
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ void draw();
protected:
- LLPanelClassifiedInfo();
-
virtual void resetData();
virtual void resetControls();
@@ -165,7 +136,6 @@ protected:
void onMapClick();
void onTeleportClick();
- void onExit();
bool mSnapshotStreched;
LLRect mSnapshotRect;
@@ -202,100 +172,4 @@ private:
static panel_list_t sAllPanels;
};
-class LLPanelClassifiedEdit : public LLPanelClassifiedInfo
-{
- LOG_CLASS(LLPanelClassifiedEdit);
-public:
-
- static LLPanelClassifiedEdit* create();
-
- virtual ~LLPanelClassifiedEdit();
-
- /*virtual*/ BOOL postBuild();
-
- void fillIn(const LLSD& key);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void resetDirty();
-
- void setSaveCallback(const commit_signal_t::slot_type& cb);
-
- void setCancelCallback(const commit_signal_t::slot_type& cb);
-
- /*virtual*/ void resetControls();
-
- bool isNew() { return mIsNew; }
-
- bool isNewWithErrors() { return mIsNewWithErrors; }
-
- bool canClose();
-
- void draw();
-
- void stretchSnapshot();
-
- U32 getCategory();
-
- void setCategory(U32 category);
-
- U32 getContentType();
-
- void setContentType(U32 content_type);
-
- bool getAutoRenew();
-
- S32 getPriceForListing();
-
-protected:
-
- LLPanelClassifiedEdit();
-
- void sendUpdate();
-
- void enableVerbs(bool enable);
-
- void enableEditing(bool enable);
-
- void showEditing(bool show);
-
- std::string makeClassifiedName();
-
- void setPriceForListing(S32 price);
-
- U8 getFlags();
-
- std::string getLocationNotice();
-
- bool isValidName();
-
- void notifyInvalidName();
-
- void onSetLocationClick();
- void onChange();
- void onSaveClick();
-
- void doSave();
-
- void onPublishFloaterPublishClicked();
-
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
- void onTextureSelected();
-
-private:
- bool mIsNew;
- bool mIsNewWithErrors;
- bool mCanClose;
-
- LLPublishClassifiedFloater* mPublishFloater;
-
- commit_signal_t mSaveButtonClickedSignal;
-};
-
#endif // LL_LLPANELCLASSIFIED_H
diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp
index a169712bd8..d17845ebc5 100644
--- a/indra/newview/llpaneleditsky.cpp
+++ b/indra/newview/llpaneleditsky.cpp
@@ -108,6 +108,8 @@ namespace
const std::string FIELD_SKY_DENSITY_DROPLET_RADIUS("droplet_radius");
const std::string FIELD_SKY_DENSITY_ICE_LEVEL("ice_level");
+ const std::string FIELD_REFLECTION_PROBE_AMBIANCE("probe_ambiance");
+
const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f);
const F32 SLIDER_SCALE_BLUE_HORIZON_DENSITY(2.0f);
const F32 SLIDER_SCALE_GLOW_R(20.0f);
@@ -150,6 +152,7 @@ BOOL LLPanelSettingsSkyAtmosTab::postBuild()
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoistureLevelChanged(); });
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onDropletRadiusChanged(); });
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onIceLevelChanged(); });
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); });
refresh();
return TRUE;
@@ -172,6 +175,7 @@ void LLPanelSettingsSkyAtmosTab::setEnabled(BOOL enabled)
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setEnabled(enabled);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setEnabled(enabled);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setEnabled(enabled);
}
}
@@ -203,10 +207,12 @@ void LLPanelSettingsSkyAtmosTab::refresh()
F32 moisture_level = mSkySettings->getSkyMoistureLevel();
F32 droplet_radius = mSkySettings->getSkyDropletRadius();
F32 ice_level = mSkySettings->getSkyIceLevel();
+ F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance();
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setValue(moisture_level);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setValue(droplet_radius);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setValue(ice_level);
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(rp_ambiance);
}
//-------------------------------------------------------------------------
@@ -311,6 +317,15 @@ void LLPanelSettingsSkyAtmosTab::onIceLevelChanged()
setIsDirty();
}
+void LLPanelSettingsSkyAtmosTab::onReflectionProbeAmbianceChanged()
+{
+ if (!mSkySettings) return;
+ F32 ambiance = getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->getValue().asReal();
+ mSkySettings->setReflectionProbeAmbiance(ambiance);
+ mSkySettings->update();
+ setIsDirty();
+}
+
//==========================================================================
LLPanelSettingsSkyCloudTab::LLPanelSettingsSkyCloudTab() :
LLPanelSettingsSky()
diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h
index cb63d40b0c..cd89e02eea 100644
--- a/indra/newview/llpaneleditsky.h
+++ b/indra/newview/llpaneleditsky.h
@@ -79,6 +79,7 @@ private:
void onMoistureLevelChanged();
void onDropletRadiusChanged();
void onIceLevelChanged();
+ void onReflectionProbeAmbianceChanged();
};
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index be11a4a9f3..ea10aa75ae 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1308,7 +1308,9 @@ void LLPanelEditWearable::changeCamera(U8 subpart)
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
{
- gMorphView->updateCamera();
+ // Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE
+ gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating());
+ gMorphView->updateCamera();
}
}
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
index 9d5afd1a6a..11111f2a2e 100644
--- a/indra/newview/llpanelexperiences.h
+++ b/indra/newview/llpanelexperiences.h
@@ -29,7 +29,6 @@
#include "llaccordionctrltab.h"
#include "llflatlistview.h"
-#include "llpanelavatar.h"
class LLExperienceItem;
class LLPanelProfile;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 71657239a6..c6e0bc5153 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -38,6 +38,7 @@
#include "llfontgl.h"
// project includes
+#include "llagent.h"
#include "llagentdata.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
@@ -45,10 +46,20 @@
#include "llcombobox.h"
#include "lldrawpoolbump.h"
#include "llface.h"
+#include "llgltfmateriallist.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h" // gInventory
+#include "llinventorymodelbackgroundfetch.h"
+#include "llfloatermediasettings.h"
+#include "llfloaterreg.h"
#include "lllineeditor.h"
#include "llmaterialmgr.h"
+#include "llmaterialeditor.h"
+#include "llmediactrl.h"
#include "llmediaentry.h"
+#include "llmenubutton.h"
#include "llnotificationsutil.h"
+#include "llpanelcontents.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -57,6 +68,8 @@
#include "lltexturectrl.h"
#include "lltextureentry.h"
#include "lltooldraganddrop.h"
+#include "lltoolface.h"
+#include "lltoolmgr.h"
#include "lltrans.h"
#include "llui.h"
#include "llviewercontrol.h"
@@ -69,18 +82,35 @@
#include "llpluginclassmedia.h"
#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
+
+
+#include "llagent.h"
+#include "llfilesystem.h"
+#include "llviewerassetupload.h"
+#include "llviewermenufile.h"
+#include "llsd.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "llinventorymodel.h"
+
+using namespace std::literals;
+
//
// Constant definitions for comboboxes
// Must match the commbobox definitions in panel_tools_texture.xml
//
const S32 MATMEDIA_MATERIAL = 0; // Material
-const S32 MATMEDIA_MEDIA = 1; // Media
+const S32 MATMEDIA_PBR = 1; // PBR
+const S32 MATMEDIA_MEDIA = 2; // Media
const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture
const S32 MATTYPE_NORMAL = 1; // Normal map
const S32 MATTYPE_SPECULAR = 2; // Specular map
const S32 ALPHAMODE_MASK = 2; // Alpha masking mode
const S32 BUMPY_TEXTURE = 18; // use supplied normal map
const S32 SHINY_TEXTURE = 4; // use supplied specular map
+const S32 PBRTYPE_BASE_COLOR = 0; // PBR Base Color
+const S32 PBRTYPE_NORMAL = 1; // PBR Normal
+const S32 PBRTYPE_METALLIC = 2; // PBR Metallic
BOOST_STATIC_ASSERT(MATTYPE_DIFFUSE == LLRender::DIFFUSE_MAP && MATTYPE_NORMAL == LLRender::NORMAL_MAP && MATTYPE_SPECULAR == LLRender::SPECULAR_MAP);
@@ -92,11 +122,23 @@ std::string USE_TEXTURE;
LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
{
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
- (radio_mat_type ? (LLRender::eTexIndex)radio_mat_type->getSelectedIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
+
+ LLRender::eTexIndex channel_to_edit = LLRender::DIFFUSE_MAP;
+ if (mComboMatMedia)
+ {
+ U32 matmedia_selection = mComboMatMedia->getCurrentIndex();
+ if (matmedia_selection == MATMEDIA_MATERIAL)
+ {
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ channel_to_edit = (LLRender::eTexIndex)radio_mat_type->getSelectedIndex();
+ }
+ if (matmedia_selection == MATMEDIA_PBR)
+ {
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_pbr_type");
+ channel_to_edit = (LLRender::eTexIndex)radio_mat_type->getSelectedIndex();
+ }
+ }
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;
@@ -154,6 +196,8 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
+ childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this);
+ childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this);
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
@@ -165,7 +209,6 @@ BOOL LLPanelFace::postBuild()
LLColorSwatchCtrl* mShinyColorSwatch;
LLComboBox* mComboTexGen;
- LLComboBox* mComboMatMedia;
LLCheckBoxCtrl *mCheckFullbright;
@@ -176,6 +219,29 @@ BOOL LLPanelFace::postBuild()
setMouseOpaque(FALSE);
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ pbr_ctrl->setDefaultImageAssetID(LLUUID::null);
+ pbr_ctrl->setBlankImageAssetID(LLUUID::null); // should there be some empty default material?
+ pbr_ctrl->setCommitCallback(boost::bind(&LLPanelFace::onCommitPbr, this, _2));
+ pbr_ctrl->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelPbr, this, _2));
+ pbr_ctrl->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectPbr, this, _2));
+ pbr_ctrl->setDragCallback(boost::bind(&LLPanelFace::onDragPbr, this, _2));
+ pbr_ctrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onPbrSelectionChanged, this, _1));
+ pbr_ctrl->setOnCloseCallback(boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2));
+
+ pbr_ctrl->setFollowsTop();
+ pbr_ctrl->setFollowsLeft();
+ pbr_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ pbr_ctrl->setBakeTextureEnabled(false);
+ pbr_ctrl->setInventoryPickType(LLTextureCtrl::PICK_MATERIAL);
+
+ // TODO - design real UI for activating live editing
+ pbr_ctrl->setRightMouseUpCallback(boost::bind(&LLPanelFace::onPbrStartEditing, this));
+ }
+
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
if(mTextureCtrl)
{
@@ -279,26 +345,38 @@ BOOL LLPanelFace::postBuild()
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
}
- mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
+ mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
if(mComboMatMedia)
{
- mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
- mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
}
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
if(radio_mat_type)
{
radio_mat_type->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
}
+ LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
+ if (radio_pbr_type)
+ {
+ radio_pbr_type->setCommitCallback(LLPanelFace::onCommitPbrType, this);
+ radio_pbr_type->selectNthItem(PBRTYPE_BASE_COLOR);
+ }
+
mCtrlGlow = getChild<LLSpinCtrl>("glow");
if(mCtrlGlow)
{
mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
}
-
+
+ mMenuClipboardColor = getChild<LLMenuButton>("clipboard_color_params_btn");
+ mMenuClipboardTexture = getChild<LLMenuButton>("clipboard_texture_params_btn");
+
+ mTitleMedia = getChild<LLMediaCtrl>("title_media");
+ mTitleMediaText = getChild<LLTextBox>("media_info");
clearCtrls();
@@ -307,17 +385,33 @@ BOOL LLPanelFace::postBuild()
LLPanelFace::LLPanelFace()
: LLPanel(),
- mIsAlpha(false)
+ mIsAlpha(false),
+ mComboMatMedia(NULL),
+ mTitleMedia(NULL),
+ mTitleMediaText(NULL),
+ mNeedMediaTitle(true)
{
- USE_TEXTURE = LLTrans::getString("use_texture");
+ USE_TEXTURE = LLTrans::getString("use_texture");
+ mCommitCallbackRegistrar.add("PanelFace.menuDoToSelected", boost::bind(&LLPanelFace::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelFace.menuEnable", boost::bind(&LLPanelFace::menuEnableItem, this, _2));
}
-
LLPanelFace::~LLPanelFace()
{
- // Children all cleaned up by default view destructor.
+ unloadMedia();
}
+void LLPanelFace::draw()
+{
+ updateCopyTexButton();
+
+ // grab media name/title and update the UI widget
+ // Todo: move it, it's preferable not to update
+ // labels inside draw
+ updateMediaTitle();
+
+ LLPanel::draw();
+}
void LLPanelFace::sendTexture()
{
@@ -442,20 +536,42 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
{
BOOL valid;
F32 value;
-
- LLRadioGroup * radio_mat_type = mPanel->getChild<LLRadioGroup>("radio_material_type");
std::string prefix;
- switch (radio_mat_type->getSelectedIndex())
+ U32 materials_media = mPanel->getChild<LLComboBox>("combobox matmedia")->getCurrentIndex();
+
+ if (MATMEDIA_PBR == materials_media)
{
- case MATTYPE_DIFFUSE:
- prefix = "Tex";
- break;
- case MATTYPE_NORMAL:
- prefix = "bumpy";
- break;
- case MATTYPE_SPECULAR:
- prefix = "shiny";
- break;
+ LLRadioGroup * radio_pbr_type = mPanel->getChild<LLRadioGroup>("radio_pbr_type");
+ switch (radio_pbr_type->getSelectedIndex())
+ {
+ case PBRTYPE_BASE_COLOR:
+ prefix = "Tex";
+ break;
+ case PBRTYPE_NORMAL:
+ prefix = "bumpy";
+ break;
+ case PBRTYPE_METALLIC:
+ prefix = "shiny";
+ break;
+ }
+ }
+ else
+ {
+ // Effectively the same as MATMEDIA_PBR sans using different radio,
+ // separate for the sake of clarity
+ LLRadioGroup * radio_mat_type = mPanel->getChild<LLRadioGroup>("radio_material_type");
+ switch (radio_mat_type->getSelectedIndex())
+ {
+ case MATTYPE_DIFFUSE:
+ prefix = "Tex";
+ break;
+ case MATTYPE_NORMAL:
+ prefix = "bumpy";
+ break;
+ case MATTYPE_SPECULAR:
+ prefix = "shiny";
+ break;
+ }
}
LLSpinCtrl * ctrlTexScaleS = mPanel->getChild<LLSpinCtrl>(prefix + "ScaleU");
@@ -806,45 +922,52 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- getChildView("button align")->setEnabled(editable);
+ childSetEnabled("button align", editable);
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
- if (combobox_matmedia)
- {
- if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
- {
- combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
- }
- }
- else
- {
- LL_WARNS() << "failed getChild for 'combobox matmedia'" << LL_ENDL;
- }
- getChildView("combobox matmedia")->setEnabled(editable);
+ if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL)
+ {
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ }
+ mComboMatMedia->setEnabled(editable);
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- if(radio_mat_type)
- {
- if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE)
- {
- radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
- }
+ if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE)
+ {
+ radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
+ }
+ radio_mat_type->setEnabled(editable);
- }
- else
- {
- LL_WARNS("Materials") << "failed getChild for 'radio_material_type'" << LL_ENDL;
- }
+ LLRadioGroup* radio_pbr_type = getChild<LLRadioGroup>("radio_pbr_type");
+ if (radio_pbr_type->getSelectedIndex() < PBRTYPE_BASE_COLOR)
+ {
+ radio_pbr_type->selectNthItem(PBRTYPE_BASE_COLOR);
+ }
+ radio_pbr_type->setEnabled(editable);
- getChildView("radio_material_type")->setEnabled(editable);
getChildView("checkbox_sync_settings")->setEnabled(editable);
childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings"));
updateVisibility();
bool identical = true; // true because it is anded below
- bool identical_diffuse = false;
- bool identical_norm = false;
- bool identical_spec = false;
+ bool identical_diffuse = false;
+ bool identical_norm = false;
+ bool identical_spec = false;
+
+ // pbr material
+ bool has_pbr_material = false;
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ LLUUID pbr_id;
+ bool identical_pbr;
+ LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr);
+ identical &= identical_pbr;
+
+ pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE);
+ pbr_ctrl->setEnabled(editable);
+ pbr_ctrl->setImageAssetID(pbr_id);
+ has_pbr_material = pbr_id.notNull();
+ }
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
@@ -856,32 +979,32 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
// Color swatch
{
- getChildView("color label")->setEnabled(editable);
+ getChildView("color label")->setEnabled(editable && !has_pbr_material);
}
- LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch");
LLColor4 color = LLColor4::white;
bool identical_color = false;
- if(mColorSwatch)
+ if(color_swatch)
{
LLSelectedTE::getColor(color, identical_color);
- LLColor4 prev_color = mColorSwatch->get();
+ LLColor4 prev_color = color_swatch->get();
- mColorSwatch->setOriginal(color);
- mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable);
+ color_swatch->setOriginal(color);
+ color_swatch->set(color, force_set_values || (prev_color != color) || !editable);
- mColorSwatch->setValid(editable);
- mColorSwatch->setEnabled( editable );
- mColorSwatch->setCanApplyImmediately( editable );
+ color_swatch->setValid(editable);
+ color_swatch->setEnabled( editable );
+ color_swatch->setCanApplyImmediately( editable );
}
// Color transparency
- getChildView("color trans")->setEnabled(editable);
+ getChildView("color trans")->setEnabled(editable && !has_pbr_material);
F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
- getChildView("ColorTrans")->setEnabled(editable);
+ getChildView("ColorTrans")->setEnabled(editable && !has_pbr_material);
// Specular map
LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec);
@@ -926,7 +1049,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
U8 bumpy = 0;
// Bumpy
- {
+ {
bool identical_bumpy = false;
LLSelectedTE::getBumpmap(bumpy,identical_bumpy);
@@ -947,7 +1070,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChildView("combobox bumpiness")->setEnabled(editable);
getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy);
getChildView("label bumpiness")->setEnabled(editable);
- }
+ }
// Texture
{
@@ -1022,10 +1145,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
texture_ctrl->setTentative(FALSE);
texture_ctrl->setEnabled(editable);
texture_ctrl->setImageAssetID(id);
- getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
- getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
- getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
- getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
texture_ctrl->setBakeTextureEnabled(TRUE);
}
@@ -1048,10 +1171,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
texture_ctrl->setTentative(TRUE);
texture_ctrl->setEnabled(editable);
texture_ctrl->setImageAssetID(id);
- getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
- getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
- getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
- getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
texture_ctrl->setBakeTextureEnabled(TRUE);
}
@@ -1140,9 +1263,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s);
getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s);
- getChildView("TexScaleU")->setEnabled(editable);
- getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull());
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexScaleU")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyScaleU")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyScaleU")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexScaleU")->setEnabled(editable);
+ getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull());
+ }
BOOL diff_scale_tentative = !(identical && identical_diff_scale_s);
BOOL norm_scale_tentative = !(identical && identical_norm_scale_s);
@@ -1179,9 +1311,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL norm_scale_tentative = !identical_norm_scale_t;
BOOL spec_scale_tentative = !identical_spec_scale_t;
- getChildView("TexScaleV")->setEnabled(editable);
- getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull());
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexScaleV")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyScaleV")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyScaleV")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexScaleV")->setEnabled(editable);
+ getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull());
+ }
if (force_set_values)
{
@@ -1225,9 +1366,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative));
getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative));
- getChildView("TexOffsetU")->setEnabled(editable);
- getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull());
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexOffsetU")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyOffsetU")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyOffsetU")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexOffsetU")->setEnabled(editable);
+ getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull());
+ }
}
{
@@ -1255,9 +1405,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative));
getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative));
- getChildView("TexOffsetV")->setEnabled(editable);
- getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull());
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexOffsetV")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyOffsetV")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyOffsetV")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexOffsetV")->setEnabled(editable);
+ getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull());
+ }
}
// Texture rotation
@@ -1281,10 +1440,19 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
F32 diff_rot_deg = diff_rotation * RAD_TO_DEG;
F32 norm_rot_deg = norm_rotation * RAD_TO_DEG;
F32 spec_rot_deg = spec_rotation * RAD_TO_DEG;
-
- getChildView("TexRot")->setEnabled(editable);
- getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull());
+
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexRot")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyRot")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyRot")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexRot")->setEnabled(editable);
+ getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull());
+ }
getChild<LLUICtrl>("TexRot")->setTentative(diff_rot_tentative);
getChild<LLUICtrl>("shinyRot")->setTentative(LLSD(norm_rot_tentative));
@@ -1301,8 +1469,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLSelectedTE::getGlow(glow,identical_glow);
getChild<LLUICtrl>("glow")->setValue(glow);
getChild<LLUICtrl>("glow")->setTentative(!identical_glow);
- getChildView("glow")->setEnabled(editable);
- getChildView("glow label")->setEnabled(editable);
+ getChildView("glow")->setEnabled(editable && !has_pbr_material);
+ getChildView("glow label")->setEnabled(editable && !has_pbr_material);
}
{
@@ -1350,42 +1518,61 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
if (mComboTexGen)
- {
+ {
S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
- BOOL enabled = editable && (index != 1);
- BOOL identical_repeats = true;
+ bool enabled = editable && (index != 1);
+ bool identical_repeats = true;
+ S32 material_selection = mComboMatMedia->getCurrentIndex();
F32 repeats = 1.0f;
- U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
+ U32 material_type = MATTYPE_DIFFUSE;
+ if (material_selection == MATMEDIA_MATERIAL)
+ {
+ material_type = radio_mat_type->getSelectedIndex();
+ }
+ else if (material_selection == MATMEDIA_PBR)
+ {
+ enabled = editable && has_pbr_material;
+ material_type = radio_pbr_type->getSelectedIndex();
+ }
LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
- switch (material_type)
- {
- default:
- case MATTYPE_DIFFUSE:
- {
- enabled = editable && !id.isNull();
- identical_repeats = identical_diff_repeats;
- repeats = repeats_diff;
- }
- break;
+ switch (material_type)
+ {
+ default:
+ case MATTYPE_DIFFUSE:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = editable && !id.isNull();
+ }
+ identical_repeats = identical_diff_repeats;
+ repeats = repeats_diff;
+ }
+ break;
- case MATTYPE_SPECULAR:
- {
- enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()));
- identical_repeats = identical_spec_repeats;
- repeats = repeats_spec;
- }
- break;
+ case MATTYPE_SPECULAR:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()));
+ }
+ identical_repeats = identical_spec_repeats;
+ repeats = repeats_spec;
+ }
+ break;
- case MATTYPE_NORMAL:
- {
- enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
- identical_repeats = identical_norm_repeats;
- repeats = repeats_norm;
- }
- break;
- }
+ case MATTYPE_NORMAL:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
+ }
+ identical_repeats = identical_norm_repeats;
+ repeats = repeats_norm;
+ }
+ break;
+ }
BOOL repeats_tentative = !identical_repeats;
@@ -1409,7 +1596,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLMaterialPtr material;
LLSelectedTEMaterial::getCurrent(material, identical);
- if (material && editable)
+ if (material && editable)
{
LL_DEBUGS("Materials") << material->asLLSD() << LL_ENDL;
@@ -1508,6 +1695,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
}
}
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (selected_count == 1);
+ mMenuClipboardColor->setEnabled(editable && single_volume);
// Set variable values for numeric expressions
LLCalc* calcp = LLCalc::getInstance();
@@ -1525,6 +1715,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
clearCtrls();
// Disable non-UICtrls
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ pbr_ctrl->setImageAssetID(LLUUID::null);
+ pbr_ctrl->setEnabled(FALSE);
+ }
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
if(texture_ctrl)
{
@@ -1568,12 +1764,772 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
+void LLPanelFace::updateCopyTexButton()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()
+ && !objectp->isPermanentEnforced() && !objectp->isInventoryPending()
+ && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1));
+ std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options");
+ mMenuClipboardTexture->setToolTip(tooltip);
+
+}
+
void LLPanelFace::refresh()
{
LL_DEBUGS("Materials") << LL_ENDL;
getState();
}
+void LLPanelFace::refreshMedia()
+{
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject* first_object = selected_objects->getFirstObject();
+
+ if (!(first_object
+ && first_object->getPCode() == LL_PCODE_VOLUME
+ && first_object->permModify()
+ ))
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ mTitleMediaText->clear();
+ clearMediaSettings();
+ return;
+ }
+
+ std::string url = first_object->getRegion()->getCapability("ObjectMedia");
+ bool has_media_capability = (!url.empty());
+
+ if (!has_media_capability)
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
+ clearMediaSettings();
+ return;
+ }
+
+ BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
+ bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
+
+ // Check modify permissions and whether any selected objects are in
+ // the process of being fetched. If they are, then we're not editable
+ if (editable)
+ {
+ LLObjectSelection::iterator iter = selected_objects->begin();
+ LLObjectSelection::iterator end = selected_objects->end();
+ for (; iter != end; ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
+ if (NULL != object)
+ {
+ if (!object->permModify())
+ {
+ LL_INFOS("LLFloaterToolsMedia")
+ << "Selection not editable due to lack of modify permissions on object id "
+ << object->getID() << LL_ENDL;
+
+ editable = false;
+ break;
+ }
+ }
+ }
+ }
+
+ // Media settings
+ bool bool_has_media = false;
+ struct media_functor : public LLSelectedTEGetFunctor<bool>
+ {
+ bool get(LLViewerObject* object, S32 face)
+ {
+ LLTextureEntry *te = object->getTE(face);
+ if (te)
+ {
+ return te->hasMedia();
+ }
+ return false;
+ }
+ } func;
+
+
+ // check if all faces have media(or, all dont have media)
+ LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media);
+
+ const LLMediaEntry default_media_data;
+
+ struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
+ {
+ functor_getter_media_data(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ LLMediaEntry get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return *(object->getTE(face)->getMediaData());
+ return mMediaEntry;
+ };
+
+ const LLMediaEntry& mMediaEntry;
+
+ } func_media_data(default_media_data);
+
+ LLMediaEntry media_data_get;
+ LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get));
+
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ std::string media_title = "";
+ // update UI depending on whether "object" (prim or face) has media
+ // and whether or not you are allowed to edit it.
+
+ getChildView("add_media")->setEnabled(editable);
+ // IF all the faces have media (or all dont have media)
+ if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo)
+ {
+ // TODO: get media title and set it.
+ mTitleMediaText->clear();
+ // if identical is set, all faces are same (whether all empty or has the same media)
+ if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia))
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ // else all faces might be empty.
+ }
+ else // there' re Different Medias' been set on on the faces.
+ {
+ media_title = multi_media_info_str;
+ }
+
+ getChildView("delete_media")->setEnabled(bool_has_media && 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.
+ {
+ // seleted faces have not identical value
+ LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data);
+
+ if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
+ {
+ media_title = multi_media_info_str;
+ }
+ else
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ }
+
+ getChildView("delete_media")->setEnabled(TRUE);
+ }
+
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
+ if (materials_media == MATMEDIA_MEDIA)
+ {
+ // currently displaying media info, navigateTo and update title
+ navigateToTitleMedia(media_title);
+ }
+ else
+ {
+ // Media can be heavy, don't keep it around
+ // MAC specific: MAC doesn't support setVolume(0) so if not
+ // unloaded, it might keep playing audio until user closes editor
+ unloadMedia();
+ mNeedMediaTitle = false;
+ }
+
+ mTitleMediaText->setText(media_title);
+
+ // load values for media settings
+ updateMediaSettings();
+
+ LLFloaterMediaSettings::initValues(mMediaSettings, editable);
+}
+
+void LLPanelFace::unloadMedia()
+{
+ // destroy media source used to grab media title
+ if (mTitleMedia)
+ mTitleMedia->unloadMediaSource();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelFace::navigateToTitleMedia( const std::string url )
+{
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ if (url.empty() || multi_media_info_str == url)
+ {
+ // nothing to show
+ mNeedMediaTitle = false;
+ }
+ else if (mTitleMedia)
+ {
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ // check if url changed or if we need a new media source
+ if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
+ {
+ mTitleMedia->navigateTo( url );
+
+ LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID());
+ if (impl)
+ {
+ // if it's a page with a movie, we don't want to hear it
+ impl->setVolume(0);
+ };
+ }
+
+ // flag that we need to update the title (even if no request were made)
+ mNeedMediaTitle = true;
+ }
+}
+
+bool LLPanelFace::selectedMediaEditable()
+{
+ U32 owner_mask_on;
+ U32 owner_mask_off;
+ U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
+ &owner_mask_on, &owner_mask_off);
+ U32 group_mask_on;
+ U32 group_mask_off;
+ U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
+ &group_mask_on, &group_mask_off);
+ U32 everyone_mask_on;
+ U32 everyone_mask_off;
+ S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
+ &everyone_mask_on, &everyone_mask_off);
+
+ bool selected_Media_editable = false;
+
+ // if perms we got back are valid
+ if (valid_owner_perms &&
+ valid_group_perms &&
+ valid_everyone_perms)
+ {
+
+ if ((owner_mask_on & PERM_MODIFY) ||
+ (group_mask_on & PERM_MODIFY) ||
+ (everyone_mask_on & PERM_MODIFY))
+ {
+ selected_Media_editable = true;
+ }
+ else
+ // user is NOT allowed to press the RESET button
+ {
+ selected_Media_editable = false;
+ };
+ };
+
+ return selected_Media_editable;
+}
+
+void LLPanelFace::clearMediaSettings()
+{
+ LLFloaterMediaSettings::clearValues(false);
+}
+
+void LLPanelFace::updateMediaSettings()
+{
+ bool identical(false);
+ std::string base_key("");
+ std::string value_str("");
+ int value_int = 0;
+ bool value_bool = false;
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ // TODO: (CP) refactor this using something clever or boost or both !!
+
+ const LLMediaEntry default_media_data;
+
+ // controls
+ U8 value_u8 = default_media_data.getControls();
+ struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
+ {
+ functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
+
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getControls();
+ return mMediaEntry.getControls();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_controls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_controls, value_u8);
+ base_key = std::string(LLMediaEntry::CONTROLS_KEY);
+ mMediaSettings[base_key] = value_u8;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // First click (formerly left click)
+ value_bool = default_media_data.getFirstClickInteract();
+ struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_first_click(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getFirstClickInteract();
+ return mMediaEntry.getFirstClickInteract();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_first_click(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_first_click, value_bool);
+ base_key = std::string(LLMediaEntry::FIRST_CLICK_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Home URL
+ value_str = default_media_data.getHomeURL();
+ struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_home_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHomeURL();
+ return mMediaEntry.getHomeURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_home_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_home_url, value_str);
+ base_key = std::string(LLMediaEntry::HOME_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Current URL
+ value_str = default_media_data.getCurrentURL();
+ struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_current_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getCurrentURL();
+ return mMediaEntry.getCurrentURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_current_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_current_url, value_str);
+ base_key = std::string(LLMediaEntry::CURRENT_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto zoom
+ value_bool = default_media_data.getAutoZoom();
+ struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
+ {
+
+ functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoZoom();
+ return mMediaEntry.getAutoZoom();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_zoom(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_zoom, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_ZOOM_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto play
+ //value_bool = default_media_data.getAutoPlay();
+ // set default to auto play TRUE -- angela EXT-5172
+ value_bool = true;
+ struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoPlay();
+ //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_play(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_play, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_PLAY_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+
+ // Auto scale
+ // set default to auto scale TRUE -- angela EXT-5172
+ //value_bool = default_media_data.getAutoScale();
+ value_bool = true;
+ struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_scale(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoScale();
+ // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_scale(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_scale, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_SCALE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto loop
+ value_bool = default_media_data.getAutoLoop();
+ struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoLoop();
+ return mMediaEntry.getAutoLoop();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_loop(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_loop, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_LOOP_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // width pixels (if not auto scaled)
+ value_int = default_media_data.getWidthPixels();
+ struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_width_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWidthPixels();
+ return mMediaEntry.getWidthPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_width_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_width_pixels, value_int);
+ base_key = std::string(LLMediaEntry::WIDTH_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // height pixels (if not auto scaled)
+ value_int = default_media_data.getHeightPixels();
+ struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHeightPixels();
+ return mMediaEntry.getHeightPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_height_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_height_pixels, value_int);
+ base_key = std::string(LLMediaEntry::HEIGHT_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Enable Alt image
+ value_bool = default_media_data.getAltImageEnable();
+ struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_enable_alt_image(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAltImageEnable();
+ return mMediaEntry.getAltImageEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_enable_alt_image(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_enable_alt_image, value_bool);
+ base_key = std::string(LLMediaEntry::ALT_IMAGE_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_interact(default_media_data);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func_perms_anyone_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_anyone_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist enable
+ value_bool = default_media_data.getWhiteListEnable();
+ struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteListEnable();
+ return mMediaEntry.getWhiteListEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_enable(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_enable, value_bool);
+ base_key = std::string(LLMediaEntry::WHITELIST_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist URLs
+ std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
+ struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
+ {
+ functor_getter_whitelist_urls(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::vector<std::string> get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteList();
+ return mMediaEntry.getWhiteList();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_urls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_urls, value_vector_str);
+ base_key = std::string(LLMediaEntry::WHITELIST_KEY);
+ mMediaSettings[base_key].clear();
+ std::vector< std::string >::iterator iter = value_vector_str.begin();
+ while (iter != value_vector_str.end())
+ {
+ std::string white_list_url = *iter;
+ mMediaSettings[base_key].append(white_list_url);
+ ++iter;
+ };
+
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+}
+
+void LLPanelFace::updateMediaTitle()
+{
+ // only get the media name if we need it
+ if (!mNeedMediaTitle)
+ return;
+
+ // get plugin impl
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ if (media_plugin && mTitleMedia->getCurrentNavUrl() == media_plugin->getNavigateURI())
+ {
+ // get the media name (asynchronous - must call repeatedly)
+ std::string media_title = media_plugin->getMediaName();
+
+ // only replace the title if what we get contains something
+ if (!media_title.empty())
+ {
+ // update the UI widget
+ if (mTitleMediaText)
+ {
+ mTitleMediaText->setText(media_title);
+
+ // stop looking for a title when we get one
+ mNeedMediaTitle = false;
+ };
+ };
+ };
+}
+
//
// Static functions
//
@@ -1632,49 +2588,58 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
self->updateShinyControls(false,true);
self->updateBumpyControls(false,true);
self->updateUI();
+ self->refreshMedia();
}
-// static
void LLPanelFace::updateVisibility()
-{
- LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess");
- LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness");
- if (!radio_mat_type || !combo_matmedia || !combo_shininess || !combo_bumpiness)
+{
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
+ LLComboBox* combo_shininess = findChild<LLComboBox>("combobox shininess");
+ LLComboBox* combo_bumpiness = findChild<LLComboBox>("combobox bumpiness");
+ if (!radio_mat_type || !radio_pbr_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
{
LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
return;
}
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled()));
- bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
- getChildView("radio_material_type")->setVisible(!show_media);
+ U32 pbr_type = radio_pbr_type->getSelectedIndex();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ bool show_material = materials_media == MATMEDIA_MATERIAL;
+ bool show_pbr = materials_media == MATMEDIA_PBR;
+ bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
+ bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
+ bool show_pbr_base_color = show_pbr && (pbr_type == PBRTYPE_BASE_COLOR) && mComboMatMedia->getEnabled();
+ bool show_pbr_normal = show_pbr && (pbr_type == PBRTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_pbr_metallic = show_pbr && (pbr_type == PBRTYPE_METALLIC) && mComboMatMedia->getEnabled();
+
+ radio_mat_type->setVisible(show_material);
+ radio_pbr_type->setVisible(show_pbr);
// Media controls
- getChildView("media_info")->setVisible(show_media);
+ mTitleMediaText->setVisible(show_media);
getChildView("add_media")->setVisible(show_media);
getChildView("delete_media")->setVisible(show_media);
getChildView("button align")->setVisible(show_media);
// Diffuse texture controls
- getChildView("texture control")->setVisible(show_texture && !show_media);
- getChildView("label alphamode")->setVisible(show_texture && !show_media);
- getChildView("combobox alphamode")->setVisible(show_texture && !show_media);
+ getChildView("texture control")->setVisible(show_texture && show_material);
+ getChildView("label alphamode")->setVisible(show_texture && show_material);
+ getChildView("combobox alphamode")->setVisible(show_texture && show_material);
getChildView("label maskcutoff")->setVisible(false);
getChildView("maskcutoff")->setVisible(false);
- if (show_texture && !show_media)
+ if ((show_texture && show_material) || show_pbr)
{
updateAlphaControls();
}
- getChildView("TexScaleU")->setVisible(show_texture);
- getChildView("TexScaleV")->setVisible(show_texture);
- getChildView("TexRot")->setVisible(show_texture);
- getChildView("TexOffsetU")->setVisible(show_texture);
- getChildView("TexOffsetV")->setVisible(show_texture);
+ // texture scale and position controls are shared between bpr and non-pbr textures
+ getChildView("TexScaleU")->setVisible(show_texture || show_pbr_base_color);
+ getChildView("TexScaleV")->setVisible(show_texture || show_pbr_base_color);
+ getChildView("TexRot")->setVisible(show_texture || show_pbr_base_color);
+ getChildView("TexOffsetU")->setVisible(show_texture || show_pbr_base_color);
+ getChildView("TexOffsetV")->setVisible(show_texture || show_pbr_base_color);
// Specular map controls
getChildView("shinytexture control")->setVisible(show_shininess);
@@ -1690,11 +2655,11 @@ void LLPanelFace::updateVisibility()
{
updateShinyControls();
}
- getChildView("shinyScaleU")->setVisible(show_shininess);
- getChildView("shinyScaleV")->setVisible(show_shininess);
- getChildView("shinyRot")->setVisible(show_shininess);
- getChildView("shinyOffsetU")->setVisible(show_shininess);
- getChildView("shinyOffsetV")->setVisible(show_shininess);
+ getChildView("shinyScaleU")->setVisible(show_shininess || show_pbr_normal);
+ getChildView("shinyScaleV")->setVisible(show_shininess || show_pbr_normal);
+ getChildView("shinyRot")->setVisible(show_shininess || show_pbr_normal);
+ getChildView("shinyOffsetU")->setVisible(show_shininess || show_pbr_normal);
+ getChildView("shinyOffsetV")->setVisible(show_shininess || show_pbr_normal);
// Normal map controls
if (show_bumpiness)
@@ -1704,13 +2669,14 @@ void LLPanelFace::updateVisibility()
getChildView("bumpytexture control")->setVisible(show_bumpiness);
getChildView("combobox bumpiness")->setVisible(show_bumpiness);
getChildView("label bumpiness")->setVisible(show_bumpiness);
- getChildView("bumpyScaleU")->setVisible(show_bumpiness);
- getChildView("bumpyScaleV")->setVisible(show_bumpiness);
- getChildView("bumpyRot")->setVisible(show_bumpiness);
- getChildView("bumpyOffsetU")->setVisible(show_bumpiness);
- getChildView("bumpyOffsetV")->setVisible(show_bumpiness);
-
-
+ getChildView("bumpyScaleU")->setVisible(show_bumpiness || show_pbr_metallic);
+ getChildView("bumpyScaleV")->setVisible(show_bumpiness || show_pbr_metallic);
+ getChildView("bumpyRot")->setVisible(show_bumpiness || show_pbr_metallic);
+ getChildView("bumpyOffsetU")->setVisible(show_bumpiness || show_pbr_metallic);
+ getChildView("bumpyOffsetV")->setVisible(show_bumpiness || show_pbr_metallic);
+
+ // PBR controls
+ getChildView("pbr_control")->setVisible(show_pbr);
}
// static
@@ -1726,6 +2692,16 @@ void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata)
}
// static
+void LLPanelFace::onCommitPbrType(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ // Force to default states to side-step problems with menu contents
+ // and generally reflecting old state when switching tabs or objects
+ //
+ self->updateUI();
+}
+
+// static
void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
@@ -1787,12 +2763,11 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh
}
- LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ bool show_material = (materials_media == MATMEDIA_MATERIAL);
+ bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
U32 shiny_value = comboShiny->getCurrentIndex();
bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
getChildView("label glossiness")->setVisible(show_shinyctrls);
@@ -1866,11 +2841,10 @@ void LLPanelFace::updateAlphaControls()
U32 alpha_value = comboAlphaMode->getCurrentIndex();
bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
U32 mat_media = MATMEDIA_MATERIAL;
- if (combobox_matmedia)
+ if (mComboMatMedia)
{
- mat_media = combobox_matmedia->getCurrentIndex();
+ mat_media = mComboMatMedia->getCurrentIndex();
}
U32 mat_type = MATTYPE_DIFFUSE;
@@ -1910,21 +2884,81 @@ void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
}
// static
+BOOL LLPanelFace::onDragPbr(LLUICtrl*, LLInventoryItem* item)
+{
+ BOOL accept = TRUE;
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if (!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
+ {
+ accept = FALSE;
+ break;
+ }
+ }
+ return accept;
+}
+
+void LLPanelFace::onCommitPbr(const LLSD& data)
+{
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (!pbr_ctrl) return;
+ if (!pbr_ctrl->getTentative())
+ {
+ // we grab the item id first, because we want to do a
+ // permissions check in the selection manager. ARGH!
+ LLUUID id = pbr_ctrl->getImageItemID();
+ if (id.isNull())
+ {
+ id = pbr_ctrl->getImageAssetID();
+ }
+ LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id);
+ }
+}
+
+void LLPanelFace::onCancelPbr(const LLSD& data)
+{
+ LLSelectMgr::getInstance()->selectionRevertGLTFMaterials();
+}
+
+void LLPanelFace::onSelectPbr(const LLSD& data)
+{
+ LLSelectMgr::getInstance()->saveSelectedObjectTextures();
+
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (!pbr_ctrl) return;
+ if (!pbr_ctrl->getTentative())
+ {
+ // we grab the item id first, because we want to do a
+ // permissions check in the selection manager. ARGH!
+ LLUUID id = pbr_ctrl->getImageItemID();
+ if (id.isNull())
+ {
+ id = pbr_ctrl->getImageAssetID();
+ }
+ LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id);
+ LLSelectedTEMaterial::setMaterialID(this, id);
+ }
+}
+
+// static
BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
{
- BOOL accept = TRUE;
- for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* obj = node->getObject();
- if(!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
- {
- accept = FALSE;
- break;
- }
- }
- return accept;
+ BOOL accept = TRUE;
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if (!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
+ {
+ accept = FALSE;
+ break;
+ }
+ }
+ return accept;
}
void LLPanelFace::onCommitTexture( const LLSD& data )
@@ -2027,6 +3061,77 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data)
sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
}
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to edit existing media settings on a prim or prim face
+// TODO: test if there is media on the item and only allow editing if present
+void LLPanelFace::onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLFloaterReg::showInstance("media_settings");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to delete media from a prim or prim face
+void LLPanelFace::onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to add media to a prim or prim face
+void LLPanelFace::onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata)
+{
+ // check if multiple faces are selected
+ if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ {
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
+ }
+ else
+ {
+ onClickBtnEditMedia(ctrl, userdata);
+ }
+}
+
+// static
+bool LLPanelFace::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLSelectMgr::getInstance()->selectionSetMedia(0, LLSD());
+ if (LLFloaterReg::instanceVisible("media_settings"))
+ {
+ LLFloaterReg::hideInstance("media_settings");
+ }
+ break;
+
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+// static
+bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLFloaterReg::showInstance("media_settings");
+ break;
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
//static
void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU)
{
@@ -2404,12 +3509,20 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
LLPanelFace* self = (LLPanelFace*) userdata;
LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
- LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia");
- LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = self->mComboMatMedia->getCurrentIndex();
+ U32 material_type = 0;
+ if (materials_media == MATMEDIA_PBR)
+ {
+ LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_pbr_type");
+ material_type = radio_mat_type->getSelectedIndex();
+ }
+ if (materials_media == MATMEDIA_MATERIAL)
+ {
+ LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type");
+ material_type = radio_mat_type->getSelectedIndex();
+ }
- U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : 0;
F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
F32 obj_scale_s = 1.0f;
@@ -2538,15 +3651,842 @@ void LLPanelFace::onAlignTexture(void* userdata)
self->alignTestureLayer();
}
+enum EPasteMode
+{
+ PASTE_COLOR,
+ PASTE_TEXTURE
+};
+
+struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor
+{
+ LLPanelFacePasteTexFunctor(LLPanelFace* panel, EPasteMode mode) :
+ mPanelFace(panel), mMode(mode) {}
+
+ virtual bool apply(LLViewerObject* objectp, S32 te)
+ {
+ switch (mMode)
+ {
+ case PASTE_COLOR:
+ mPanelFace->onPasteColor(objectp, te);
+ break;
+ case PASTE_TEXTURE:
+ mPanelFace->onPasteTexture(objectp, te);
+ break;
+ }
+ return true;
+ }
+private:
+ LLPanelFace *mPanelFace;
+ EPasteMode mMode;
+};
+
+struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
+{
+ LLPanelFaceUpdateFunctor(bool update_media, bool update_pbr)
+ : mUpdateMedia(update_media)
+ , mUpdatePbr(update_pbr)
+ {}
+
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (mUpdatePbr)
+ {
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ object->setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+ }
+
+ object->sendTEUpdate();
+
+ if (mUpdateMedia)
+ {
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+ if (vo && vo->hasMedia())
+ {
+ vo->sendMediaDataUpdate();
+ }
+ }
+ return true;
+ }
+private:
+ bool mUpdateMedia;
+ bool mUpdatePbr;
+};
+
+struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor
+{
+ virtual bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (objectp && objectp->getTE(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ const LLMediaEntry *media_data = tep->getMediaData();
+ if (media_data)
+ {
+ if (media_data->getCurrentURL().empty() && media_data->getAutoPlay())
+ {
+ viewer_media_t media_impl =
+ LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID());
+ if (media_impl)
+ {
+ media_impl->navigateHome();
+ }
+ }
+ }
+ }
+ return true;
+ }
+};
+
+void LLPanelFace::onCopyColor()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ return;
+ }
+
+ if (mClipboardParams.has("color"))
+ {
+ mClipboardParams["color"].clear();
+ }
+ else
+ {
+ mClipboardParams["color"] = LLSD::emptyArray();
+ }
+
+ std::map<LLUUID, LLUUID> asset_item_map;
+
+ // a way to resolve situations where source and target have different amount of faces
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ mClipboardParams["color_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ LLSD te_data;
+
+ // asLLSD() includes media
+ te_data["te"] = tep->asLLSD(); // Note: includes a lot more than just color/alpha/glow
+
+ mClipboardParams["color"].append(te_data);
+ }
+ }
+ }
+}
-// TODO: I don't know who put these in or what these are for???
-void LLPanelFace::setMediaURL(const std::string& url)
+void LLPanelFace::onPasteColor()
{
+ if (!mClipboardParams.has("color"))
+ {
+ return;
+ }
+
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ // not supposed to happen
+ LL_WARNS() << "Failed to paste color due to missing or wrong selection" << LL_ENDL;
+ return;
+ }
+
+ bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ LLSD &clipboard = mClipboardParams["color"]; // array
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ S32 compare_tes = num_tes;
+
+ if (face_selection_mode)
+ {
+ compare_tes = 0;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ compare_tes++;
+ }
+ }
+ }
+
+ // we can copy if single face was copied in edit face mode or if face count matches
+ if (!((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean())
+ && compare_tes != clipboard.size())
+ {
+ LLSD notif_args;
+ if (face_selection_mode)
+ {
+ static std::string reason = getString("paste_error_face_selection_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ else
+ {
+ static std::string reason = getString("paste_error_object_face_count_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+
+ LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR);
+ selected_objects->applyToTEs(&paste_func);
+
+ LLPanelFaceUpdateFunctor sendfunc(false, false);
+ selected_objects->applyToObjects(&sendfunc);
}
-void LLPanelFace::setMediaType(const std::string& mime_type)
+
+void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te)
{
+ LLSD te_data;
+ LLSD &clipboard = mClipboardParams["color"]; // array
+ if ((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean())
+ {
+ te_data = *(clipboard.beginArray());
+ }
+ else if (clipboard[te])
+ {
+ te_data = clipboard[te];
+ }
+ else
+ {
+ return;
+ }
+
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ if (te_data.has("te"))
+ {
+ // Color / Alpha
+ if (te_data["te"].has("colors"))
+ {
+ LLColor4 color = tep->getColor();
+
+ LLColor4 clip_color;
+ clip_color.setValue(te_data["te"]["colors"]);
+
+ // Color
+ color.mV[VRED] = clip_color.mV[VRED];
+ color.mV[VGREEN] = clip_color.mV[VGREEN];
+ color.mV[VBLUE] = clip_color.mV[VBLUE];
+
+ // Alpha
+ color.mV[VALPHA] = clip_color.mV[VALPHA];
+
+ objectp->setTEColor(te, color);
+ }
+
+ // Color/fullbright
+ if (te_data["te"].has("fullbright"))
+ {
+ objectp->setTEFullbright(te, te_data["te"]["fullbright"].asInteger());
+ }
+
+ // Glow
+ if (te_data["te"].has("glow"))
+ {
+ objectp->setTEGlow(te, (F32)te_data["te"]["glow"].asReal());
+ }
+ }
+ }
}
+void LLPanelFace::onCopyTexture()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ return;
+ }
+
+ if (mClipboardParams.has("texture"))
+ {
+ mClipboardParams["texture"].clear();
+ }
+ else
+ {
+ mClipboardParams["texture"] = LLSD::emptyArray();
+ }
+
+ std::map<LLUUID, LLUUID> asset_item_map;
+
+ // a way to resolve situations where source and target have different amount of faces
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ mClipboardParams["texture_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ LLSD te_data;
+
+ // asLLSD() includes media
+ te_data["te"] = tep->asLLSD();
+ te_data["te"]["shiny"] = tep->getShiny();
+ te_data["te"]["bumpmap"] = tep->getBumpmap();
+ te_data["te"]["bumpshiny"] = tep->getBumpShiny();
+ te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright();
+ te_data["te"]["pbr"] = objectp->getRenderMaterialID(te);
+
+ if (te_data["te"].has("imageid"))
+ {
+ LLUUID item_id;
+ LLUUID id = te_data["te"]["imageid"].asUUID();
+ bool from_library = get_is_predefined_texture(id);
+ bool full_perm = from_library;
+
+ if (!full_perm
+ && objectp->permCopy()
+ && objectp->permTransfer()
+ && objectp->permModify())
+ {
+ // If agent created this object and nothing is limiting permissions, mark as full perm
+ // If agent was granted permission to edit objects owned and created by somebody else, mark full perm
+ // This check is not perfect since we can't figure out whom textures belong to so this ended up restrictive
+ std::string creator_app_link;
+ LLUUID creator_id;
+ LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_app_link);
+ full_perm = objectp->mOwnerID == creator_id;
+ }
+
+ if (id.notNull() && !full_perm)
+ {
+ std::map<LLUUID, LLUUID>::iterator iter = asset_item_map.find(id);
+ if (iter != asset_item_map.end())
+ {
+ item_id = iter->second;
+ }
+ else
+ {
+ // What this does is simply searches inventory for item with same asset id,
+ // as result it is Hightly unreliable, leaves little control to user, borderline hack
+ // but there are little options to preserve permissions - multiple inventory
+ // items might reference same asset and inventory search is expensive.
+ bool no_transfer = false;
+ if (objectp->getInventoryItemByAsset(id))
+ {
+ no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm();
+ }
+ item_id = get_copy_free_item_by_asset_id(id, no_transfer);
+ // record value to avoid repeating inventory search when possible
+ asset_item_map[id] = item_id;
+ }
+ }
+
+ if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID()))
+ {
+ full_perm = true;
+ from_library = true;
+ }
+
+ {
+ te_data["te"]["itemfullperm"] = full_perm;
+ te_data["te"]["fromlibrary"] = from_library;
+
+ // If full permission object, texture is free to copy,
+ // but otherwise we need to check inventory and extract permissions
+ //
+ // Normally we care only about restrictions for current user and objects
+ // don't inherit any 'next owner' permissions from texture, so there is
+ // no need to record item id if full_perm==true
+ if (!full_perm && !from_library && item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (itemp)
+ {
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ te_data["te"]["imageitemid"] = item_id;
+ te_data["te"]["itemfullperm"] = itemp->getIsFullPerm();
+ if (!itemp->isFinished())
+ {
+ // needed for dropTextureAllFaces
+ LLInventoryModelBackgroundFetch::instance().start(item_id, false);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ LLMaterialPtr material_ptr = tep->getMaterialParams();
+ if (!material_ptr.isNull())
+ {
+ LLSD mat_data;
+
+ mat_data["NormMap"] = material_ptr->getNormalID();
+ mat_data["SpecMap"] = material_ptr->getSpecularID();
+
+ mat_data["NormRepX"] = material_ptr->getNormalRepeatX();
+ mat_data["NormRepY"] = material_ptr->getNormalRepeatY();
+ mat_data["NormOffX"] = material_ptr->getNormalOffsetX();
+ mat_data["NormOffY"] = material_ptr->getNormalOffsetY();
+ mat_data["NormRot"] = material_ptr->getNormalRotation();
+
+ mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX();
+ mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY();
+ mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX();
+ mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY();
+ mat_data["SpecRot"] = material_ptr->getSpecularRotation();
+
+ mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue();
+ mat_data["SpecExp"] = material_ptr->getSpecularLightExponent();
+ mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity();
+ mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff();
+ mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode();
+
+ // Replace no-copy textures, destination texture will get used instead if available
+ if (mat_data.has("NormMap"))
+ {
+ LLUUID id = mat_data["NormMap"].asUUID();
+ if (id.notNull() && !get_can_copy_texture(id))
+ {
+ mat_data["NormMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
+ mat_data["NormMapNoCopy"] = true;
+ }
+
+ }
+ if (mat_data.has("SpecMap"))
+ {
+ LLUUID id = mat_data["SpecMap"].asUUID();
+ if (id.notNull() && !get_can_copy_texture(id))
+ {
+ mat_data["SpecMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
+ mat_data["SpecMapNoCopy"] = true;
+ }
+
+ }
+
+ te_data["material"] = mat_data;
+ }
+
+ mClipboardParams["texture"].append(te_data);
+ }
+ }
+ }
+}
+
+void LLPanelFace::onPasteTexture()
+{
+ if (!mClipboardParams.has("texture"))
+ {
+ return;
+ }
+
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ // not supposed to happen
+ LL_WARNS() << "Failed to paste texture due to missing or wrong selection" << LL_ENDL;
+ return;
+ }
+
+ bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ LLSD &clipboard = mClipboardParams["texture"]; // array
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ S32 compare_tes = num_tes;
+
+ if (face_selection_mode)
+ {
+ compare_tes = 0;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ compare_tes++;
+ }
+ }
+ }
+
+ // we can copy if single face was copied in edit face mode or if face count matches
+ if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean())
+ && compare_tes != clipboard.size())
+ {
+ LLSD notif_args;
+ if (face_selection_mode)
+ {
+ static std::string reason = getString("paste_error_face_selection_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ else
+ {
+ static std::string reason = getString("paste_error_object_face_count_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+
+ bool full_perm_object = true;
+ LLSD::array_const_iterator iter = clipboard.beginArray();
+ LLSD::array_const_iterator end = clipboard.endArray();
+ for (; iter != end; ++iter)
+ {
+ const LLSD& te_data = *iter;
+ if (te_data.has("te") && te_data["te"].has("imageid"))
+ {
+ bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean();
+ full_perm_object &= full_perm;
+ if (!full_perm)
+ {
+ if (te_data["te"].has("imageitemid"))
+ {
+ LLUUID item_id = te_data["te"]["imageitemid"].asUUID();
+ if (item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (!itemp)
+ {
+ // image might be in object's inventory, but it can be not up to date
+ LLSD notif_args;
+ static std::string reason = getString("paste_error_inventory_not_found");
+ notif_args["REASON"] = reason;
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+ }
+ }
+ else
+ {
+ // Item was not found on 'copy' stage
+ // Since this happened at copy, might be better to either show this
+ // at copy stage or to drop clipboard here
+ LLSD notif_args;
+ static std::string reason = getString("paste_error_inventory_not_found");
+ notif_args["REASON"] = reason;
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+ }
+ }
+ }
+
+ if (!full_perm_object)
+ {
+ LLNotificationsUtil::add("FacePasteTexturePermissions");
+ }
+
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+
+ LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE);
+ selected_objects->applyToTEs(&paste_func);
+
+ LLPanelFaceUpdateFunctor sendfunc(true, true);
+ selected_objects->applyToObjects(&sendfunc);
+
+ LLPanelFaceNavigateHomeFunctor navigate_home_func;
+ selected_objects->applyToTEs(&navigate_home_func);
+}
+
+void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
+{
+ LLSD te_data;
+ LLSD &clipboard = mClipboardParams["texture"]; // array
+ if ((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean())
+ {
+ te_data = *(clipboard.beginArray());
+ }
+ else if (clipboard[te])
+ {
+ te_data = clipboard[te];
+ }
+ else
+ {
+ return;
+ }
+
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ if (te_data.has("te"))
+ {
+ // Texture
+ bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean();
+ bool from_library = te_data["te"].has("fromlibrary") && te_data["te"]["fromlibrary"].asBoolean();
+ if (te_data["te"].has("imageid"))
+ {
+ const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id
+ LLViewerInventoryItem* itemp_res = NULL;
+
+ if (te_data["te"].has("imageitemid"))
+ {
+ LLUUID item_id = te_data["te"]["imageitemid"].asUUID();
+ if (item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (itemp && itemp->isFinished())
+ {
+ // dropTextureAllFaces will fail if incomplete
+ itemp_res = itemp;
+ }
+ else
+ {
+ // Theoretically shouldn't happend, but if it does happen, we
+ // might need to add a notification to user that paste will fail
+ // since inventory isn't fully loaded
+ LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL;
+ }
+ }
+ }
+ // for case when item got removed from inventory after we pressed 'copy'
+ // or texture got pasted into previous object
+ if (!itemp_res && !full_perm)
+ {
+ // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable.
+ LL_INFOS() << "Item " << te_data["te"]["imageitemid"].asUUID() << " no longer in inventory." << LL_ENDL;
+ // Todo: fix this, we are often searching same texture multiple times (equal to number of faces)
+ // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(imageid);
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ // Extremely unreliable and perfomance unfriendly.
+ // But we need this to check permissions and it is how texture control finds items
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLViewerInventoryItem* itemp = items[i];
+ if (itemp && itemp->isFinished())
+ {
+ // dropTextureAllFaces will fail if incomplete
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ itemp_res = itemp;
+ break; // first match
+ }
+ }
+ }
+ }
+
+ if (itemp_res)
+ {
+ if (te == -1) // all faces
+ {
+ LLToolDragAndDrop::dropTextureAllFaces(objectp,
+ itemp_res,
+ from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT,
+ LLUUID::null);
+ }
+ else // one face
+ {
+ LLToolDragAndDrop::dropTextureOneFace(objectp,
+ te,
+ itemp_res,
+ from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT,
+ LLUUID::null,
+ 0);
+ }
+ }
+ // not an inventory item or no complete items
+ else if (full_perm)
+ {
+ // Either library, local or existed as fullperm when user made a copy
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ objectp->setTEImage(U8(te), image);
+ }
+ }
+
+ if (te_data["te"].has("bumpmap"))
+ {
+ objectp->setTEBumpmap(te, (U8)te_data["te"]["bumpmap"].asInteger());
+ }
+ if (te_data["te"].has("bumpshiny"))
+ {
+ objectp->setTEBumpShiny(te, (U8)te_data["te"]["bumpshiny"].asInteger());
+ }
+ if (te_data["te"].has("bumpfullbright"))
+ {
+ objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger());
+ }
+ if (te_data["te"].has("pbr"))
+ {
+ objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false);
+ }
+ else
+ {
+ objectp->setRenderMaterialID(te, LLUUID::null, false);
+ }
+
+ // Texture map
+ if (te_data["te"].has("scales") && te_data["te"].has("scalet"))
+ {
+ objectp->setTEScale(te, (F32)te_data["te"]["scales"].asReal(), (F32)te_data["te"]["scalet"].asReal());
+ }
+ if (te_data["te"].has("offsets") && te_data["te"].has("offsett"))
+ {
+ objectp->setTEOffset(te, (F32)te_data["te"]["offsets"].asReal(), (F32)te_data["te"]["offsett"].asReal());
+ }
+ if (te_data["te"].has("imagerot"))
+ {
+ objectp->setTERotation(te, (F32)te_data["te"]["imagerot"].asReal());
+ }
+
+ // Media
+ if (te_data["te"].has("media_flags"))
+ {
+ U8 media_flags = te_data["te"]["media_flags"].asInteger();
+ objectp->setTEMediaFlags(te, media_flags);
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(objectp);
+ if (vo && te_data["te"].has(LLTextureEntry::TEXTURE_MEDIA_DATA_KEY))
+ {
+ vo->syncMediaData(te, te_data["te"][LLTextureEntry::TEXTURE_MEDIA_DATA_KEY], true/*merge*/, true/*ignore_agent*/);
+ }
+ }
+ else
+ {
+ // Keep media flags on destination unchanged
+ }
+ }
+
+ if (te_data.has("material"))
+ {
+ LLUUID object_id = objectp->getID();
+
+ LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
+
+ // Normal
+ // Replace placeholders with target's
+ if (te_data["material"].has("NormMapNoCopy"))
+ {
+ LLMaterialPtr material = tep->getMaterialParams();
+ if (material.notNull())
+ {
+ LLUUID id = material->getNormalID();
+ if (id.notNull())
+ {
+ te_data["material"]["NormMap"] = id;
+ }
+ }
+ }
+ LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id);
+ LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id);
+
+ // Specular
+ // Replace placeholders with target's
+ if (te_data["material"].has("SpecMapNoCopy"))
+ {
+ LLMaterialPtr material = tep->getMaterialParams();
+ if (material.notNull())
+ {
+ LLUUID id = material->getSpecularID();
+ if (id.notNull())
+ {
+ te_data["material"]["SpecMap"] = id;
+ }
+ }
+ }
+ LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id);
+ LLColor4 spec_color(te_data["material"]["SpecColor"]);
+ LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te);
+ LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id);
+ LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id);
+ LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
+ if (te_data.has("te") && te_data["te"].has("shiny"))
+ {
+ objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger());
+ }
+ }
+ }
+}
+
+void LLPanelFace::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "color_paste")
+ {
+ onPasteColor();
+ }
+ else if (command == "texture_paste")
+ {
+ onPasteTexture();
+ }
+ // copy
+ else if (command == "color_copy")
+ {
+ onCopyColor();
+ }
+ else if (command == "texture_copy")
+ {
+ onCopyTexture();
+ }
+}
+
+bool LLPanelFace::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "color_paste")
+ {
+ return mClipboardParams.has("color");
+ }
+ else if (command == "texture_paste")
+ {
+ return mClipboardParams.has("texture");
+ }
+ return false;
+}
+
+
// static
void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
{
@@ -2607,6 +4547,50 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
}
}
+void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp)
+{
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ LLUUID obj_owner_id;
+ std::string obj_owner_name;
+ LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
+
+ LLSaleInfo sale_info;
+ LLSelectMgr::instance().selectGetSaleInfo(sale_info);
+
+ bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture?
+ bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture?
+ bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent?
+ bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale?
+
+ if (can_copy && can_transfer)
+ {
+ pbr_ctrl->setCanApply(true, true);
+ return;
+ }
+
+ // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale
+ pbr_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
+
+ if (gSavedSettings.getBOOL("TextureLivePreview"))
+ {
+ LLNotificationsUtil::add("LivePreviewUnavailable");
+ }
+ }
+}
+
+void LLPanelFace::onPbrStartEditing()
+{
+ bool identical;
+ LLUUID material_id;
+ LLSelectedTE::getPbrMaterialId(material_id, identical);
+
+ LL_DEBUGS() << "loading material live editor with asset " << material_id << LL_ENDL;
+
+ LLMaterialEditor::loadLive();
+}
+
bool LLPanelFace::isIdenticalPlanarTexgen()
{
LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
@@ -2686,6 +4670,18 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
}
+void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical)
+{
+ struct LLSelectedTEGetmatId : public LLSelectedTEGetFunctor<LLUUID>
+ {
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ return object->getRenderMaterialID(te_index);
+ }
+ } func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, id);
+}
+
void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material)
{
struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr>
@@ -2824,3 +4820,4 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic
} max_diff_repeats_func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );
}
+
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 2d57d89a44..cc46116545 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -47,6 +47,8 @@ class LLUICtrl;
class LLViewerObject;
class LLFloater;
class LLMaterialID;
+class LLMediaCtrl;
+class LLMenuButton;
// Represents an edit for use in replicating the op across one or more materials in the selection set.
//
@@ -97,8 +99,10 @@ public:
virtual ~LLPanelFace();
void refresh();
- void setMediaURL(const std::string& url);
- void setMediaType(const std::string& mime_type);
+ void refreshMedia();
+ void unloadMedia();
+
+ /*virtual*/ void draw();
LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
{
@@ -114,6 +118,12 @@ public:
LLRender::eTexIndex getTextureChannelToEdit();
protected:
+ void navigateToTitleMedia(const std::string url);
+ bool selectedMediaEditable();
+ void clearMediaSettings();
+ void updateMediaSettings();
+ void updateMediaTitle();
+
void getState();
void sendTexture(); // applies and sends texture
@@ -125,9 +135,15 @@ protected:
void sendShiny(U32 shininess); // applies and sends shininess
void sendFullbright(); // applies and sends full bright
void sendGlow();
- void sendMedia();
void alignTestureLayer();
+ void updateCopyTexButton();
+
+ void onCommitPbr(const LLSD& data);
+ void onCancelPbr(const LLSD& data);
+ void onSelectPbr(const LLSD& data);
+ static BOOL onDragPbr(LLUICtrl* ctrl, LLInventoryItem* item);
+
// this function is to return TRUE if the drag should succeed.
static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
@@ -150,6 +166,9 @@ protected:
void onCloseTexturePicker(const LLSD& data);
+ static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
+ static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
+
// Make UI reflect state of currently selected material (refresh)
// and UI mode (e.g. editing normal map v diffuse map)
//
@@ -191,9 +210,14 @@ protected:
static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialID( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
+ static void onCommitPbrType(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata);
static void onCommitBump( LLUICtrl* ctrl, void* userdata);
static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
@@ -205,6 +229,18 @@ protected:
static void onClickAutoFix(void*);
static void onAlignTexture(void*);
+public: // needs to be accessible to selection manager
+ void onCopyColor(); // records all selected faces
+ void onPasteColor(); // to specific face
+ void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face
+ void onCopyTexture();
+ void onPasteTexture();
+ void onPasteTexture(LLViewerObject* objectp, S32 te);
+
+protected:
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
+
static F32 valueGlow(LLViewerObject* object, S32 face);
@@ -234,6 +270,10 @@ private:
F32 getCurrentShinyOffsetU();
F32 getCurrentShinyOffsetV();
+ LLComboBox *mComboMatMedia;
+ LLMediaCtrl *mTitleMedia;
+ LLTextBox *mTitleMediaText;
+
// Update visibility of controls to match current UI mode
// (e.g. materials vs media editing)
//
@@ -241,10 +281,6 @@ private:
//
void updateVisibility();
- // Make material(s) reflect current state of UI (apply edit)
- //
- void updateMaterial();
-
// Hey look everyone, a type-safe alternative to copy and paste! :)
//
@@ -400,7 +436,12 @@ private:
* If agent selects texture which is not allowed to be applied for the currently selected object,
* all controls of the floater texture picker which allow to apply the texture will be disabled.
*/
- void onTextureSelectionChanged(LLInventoryItem* itemp);
+ void onTextureSelectionChanged(LLInventoryItem* itemp);
+ void onPbrSelectionChanged(LLInventoryItem* itemp);
+ void onPbrStartEditing();
+
+ LLMenuButton* mMenuClipboardColor;
+ LLMenuButton* mMenuClipboardTexture;
bool mIsAlpha;
@@ -415,7 +456,12 @@ private:
* up-arrow on a spinner, and avoids running afoul of its throttle.
*/
bool mUpdateInFlight;
- bool mUpdatePending;
+ bool mUpdatePending;
+
+ LLSD mClipboardParams;
+
+ LLSD mMediaSettings;
+ bool mNeedMediaTitle;
public:
#if defined(DEF_GET_MAT_STATE)
@@ -497,6 +543,7 @@ public:
DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);
DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);
DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor);
+ DEF_EDIT_MAT_STATE(LLUUID, const LLUUID&, setMaterialID);
};
class LLSelectedTE
@@ -506,6 +553,7 @@ public:
static void getFace(class LLFace*& face_to_return, bool& identical_face);
static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
static void getTexId(LLUUID& id, bool& identical);
+ static void getPbrMaterialId(LLUUID& id, bool& identical);
static void getObjectScaleS(F32& scale_s, bool& identical);
static void getObjectScaleT(F32& scale_t, bool& identical);
static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 375daf60f8..04d3236bf1 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -97,6 +97,7 @@ BOOL LLPanelGroupGeneral::postBuild()
mEditCharter->setCommitCallback(onCommitAny, this);
mEditCharter->setFocusReceivedCallback(boost::bind(onFocusEdit, _1, this));
mEditCharter->setFocusChangedCallback(boost::bind(onFocusEdit, _1, this));
+ mEditCharter->setContentTrusted(false);
}
// Options
@@ -575,7 +576,8 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
if (mEditCharter)
{
- mEditCharter->setText(gdatap->mCharter);
+ mEditCharter->setParseURLs(!mAllowEdit || !can_change_ident);
+ mEditCharter->setText(gdatap->mCharter);
}
resetDirty();
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index ab32ea3956..82f880c9ee 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -156,6 +156,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 389baa86cd..07a8641a92 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -1,6 +1,6 @@
/**
- * @file llpanelavatar.cpp
- * @brief LLPanelAvatar and related class implementations
+ * @file llpanelimcontrolpanel.cpp
+ * @brief LLPanelIMControlPanel and related class implementations
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp
index e7bdc51b4a..9e3fc54477 100644
--- a/indra/newview/llpanellandaudio.cpp
+++ b/indra/newview/llpanellandaudio.cpp
@@ -97,6 +97,9 @@ BOOL LLPanelLandAudio::postBuild()
mCheckAVSoundGroup = getChild<LLCheckBoxCtrl>("group av sound check");
childSetCommitCallback("group av sound check", onCommitAny, this);
+ mCheckObscureMOAP = getChild<LLCheckBoxCtrl>("obscure_moap");
+ childSetCommitCallback("obscure_moap", onCommitAny, this);
+
return TRUE;
}
@@ -157,6 +160,9 @@ void LLPanelLandAudio::refresh()
mCheckAVSoundGroup->set(parcel->getAllowGroupAVSounds() || parcel->getAllowAnyAVSounds()); // On if "Everyone" is on
mCheckAVSoundGroup->setEnabled(can_change_av_sounds && !parcel->getAllowAnyAVSounds()); // Enabled if "Everyone" is off
+
+ mCheckObscureMOAP->set(parcel->getObscureMOAP());
+ mCheckObscureMOAP->setEnabled(can_change_media);
}
}
// static
@@ -184,6 +190,8 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
group_av_sound = self->mCheckAVSoundGroup->get();
}
+ bool obscure_moap = self->mCheckObscureMOAP->get();
+
// Remove leading/trailing whitespace (common when copying/pasting)
LLStringUtil::trim(music_url);
@@ -194,6 +202,7 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
parcel->setMusicURL(music_url);
parcel->setAllowAnyAVSounds(any_av_sound);
parcel->setAllowGroupAVSounds(group_av_sound);
+ parcel->setObscureMOAP(obscure_moap);
// Send current parcel data upstream to server
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h
index 7e4fce80e4..b54fe62179 100644
--- a/indra/newview/llpanellandaudio.h
+++ b/indra/newview/llpanellandaudio.h
@@ -53,6 +53,7 @@ private:
LLLineEditor* mMusicURLEdit;
LLCheckBoxCtrl* mCheckAVSoundAny;
LLCheckBoxCtrl* mCheckAVSoundGroup;
+ LLCheckBoxCtrl* mCheckObscureMOAP;
LLSafeHandle<LLParcelSelection>& mParcel;
};
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index ce17da3076..c3334605ae 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -29,6 +29,7 @@
#include "llpanellandmarks.h"
#include "llbutton.h"
+#include "llfloaterprofile.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llsdutil.h"
@@ -1003,17 +1004,6 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
return can_be_modified;
}
-void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params)
-{
- pick_panel->setVisible(FALSE);
- owner->removeChild(pick_panel);
- //we need remove observer to avoid processParcelInfo in the future.
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(params["parcel_id"].asUUID(), this);
-
- delete pick_panel;
- pick_panel = NULL;
-}
-
bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept)
{
*accept = ACCEPT_NO;
@@ -1080,49 +1070,21 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
LLInventoryItem* inv_item,
const LLParcelData& parcel_data)
{
- LLPanelPickEdit* panel_pick = LLPanelPickEdit::create();
LLVector3d landmark_global_pos;
landmark->getGlobalPos(landmark_global_pos);
- // let's toggle pick panel into panel places
- LLPanel* panel_places = NULL;
- LLFloaterSidePanelContainer* floaterp = LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("places");
- if (floaterp)
- {
- panel_places = floaterp->findChild<LLPanel>("main_panel");
- }
-
- if (!panel_places)
- {
- llassert(NULL != panel_places);
- return;
- }
- panel_places->addChild(panel_pick);
- LLRect paren_rect(panel_places->getRect());
- panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE);
- panel_pick->setRect(paren_rect);
- panel_pick->onOpen(LLSD());
-
LLPickData data;
data.pos_global = landmark_global_pos;
data.name = inv_item->getName();
data.desc = inv_item->getDescription();
data.snapshot_id = parcel_data.snapshot_id;
data.parcel_id = parcel_data.parcel_id;
- panel_pick->setPickData(&data);
-
- LLSD params;
- params["parcel_id"] = parcel_data.parcel_id;
- /* set exit callback to get back onto panel places
- in callback we will make cleaning up( delete pick_panel instance,
- remove landmark panel from observer list
- */
- panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index d7408269b5..16f3a5dc24 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -34,7 +34,6 @@
#include "llinventorymodel.h"
#include "lllandmarklist.h"
#include "llpanelplacestab.h"
-#include "llpanelpick.h"
#include "llremoteparcelrequest.h"
class LLAccordionCtrlTab;
@@ -136,7 +135,6 @@ private:
* For now it checks cut/rename/delete/paste actions.
*/
bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
- void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
/**
* Landmark actions callbacks. Fire when a landmark is loaded from the list.
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 381b80fb66..9df3a8e31a 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -92,44 +92,6 @@ LLPointer<LLCredential> load_user_credentials(std::string &user_key)
}
}
-// keys are lower case to be case insensitive so they are not always
-// identical to names which retain user input, like:
-// "AwEsOmE Resident" -> "awesome_resident"
-std::string get_user_key_from_name(const std::string &username)
-{
- std::string key = username;
- LLStringUtil::trim(key);
- LLStringUtil::toLower(key);
- if (!LLGridManager::getInstance()->isSystemGrid())
- {
- size_t separator_index = username.find_first_of(" ");
- if (separator_index == username.npos)
- {
- // CRED_IDENTIFIER_TYPE_ACCOUNT
- return key;
- }
- }
- // CRED_IDENTIFIER_TYPE_AGENT
- size_t separator_index = username.find_first_of(" ._");
- std::string first = username.substr(0, separator_index);
- std::string last;
- if (separator_index != username.npos)
- {
- last = username.substr(separator_index + 1, username.npos);
- LLStringUtil::trim(last);
- }
- else
- {
- // ...on Linden grids, single username users as considered to have
- // last name "Resident"
- // *TODO: Make login.cgi support "account_name" like above
- last = "resident";
- }
-
- key = first + "_" + last;
- return key;
-}
-
class LLLoginLocationAutoHandler : public LLCommandHandler
{
public:
@@ -361,11 +323,10 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
username_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
username_combo->setKeystrokeOnEsc(TRUE);
- if (!mFirstLoginThisInstall)
- {
- LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
- remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
- }
+
+ LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
+ remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
+ getChild<LLCheckBoxCtrl>("remember_password")->setCommitCallback(boost::bind(&LLPanelLogin::onRememberPasswordCheck, this));
}
void LLPanelLogin::addFavoritesToStartLocation()
@@ -438,10 +399,22 @@ void LLPanelLogin::addFavoritesToStartLocation()
combo->addSeparator();
LL_DEBUGS() << "Loading favorites for " << iter->first << LL_ENDL;
LLSD user_llsd = iter->second;
+ bool update_password_setting = true;
for (LLSD::array_const_iterator iter1 = user_llsd.beginArray();
iter1 != user_llsd.endArray(); ++iter1)
{
- std::string label = (*iter1)["name"].asString();
+ if ((*iter1).has("save_password"))
+ {
+ bool save_password = (*iter1)["save_password"].asBoolean();
+ gSavedSettings.setBOOL("RememberPassword", save_password);
+ if (!save_password)
+ {
+ getChild<LLButton>("connect_btn")->setEnabled(false);
+ }
+ update_password_setting = false;
+ }
+
+ std::string label = (*iter1)["name"].asString();
std::string value = (*iter1)["slurl"].asString();
if(label != "" && value != "")
{
@@ -453,6 +426,10 @@ void LLPanelLogin::addFavoritesToStartLocation()
}
}
}
+ if (update_password_setting)
+ {
+ gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE);
+ }
break;
}
if (combo->getValue().asString().empty())
@@ -565,21 +542,12 @@ void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remem
LL_WARNS() << "Attempted fillFields with no login view shown" << LL_ENDL;
return;
}
- if (sInstance->mFirstLoginThisInstall)
- {
- LLUICtrl* remember_check = sInstance->getChild<LLUICtrl>("remember_check");
- remember_check->setValue(remember_psswrd);
- // no list to populate
- setFields(credential);
- }
- else
- {
- sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
- LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password");
- remember_password->setValue(remember_user && remember_psswrd);
- remember_password->setEnabled(remember_user);
- sInstance->populateUserList(credential);
- }
+
+ sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
+ LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password");
+ remember_password->setValue(remember_user && remember_psswrd);
+ remember_password->setEnabled(remember_user);
+ sInstance->populateUserList(credential);
}
//static
@@ -690,39 +658,6 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
// determine if the username is a first/last form or not.
size_t separator_index = username.find_first_of(' ');
- if (separator_index == username.npos
- && !LLGridManager::getInstance()->isSystemGrid())
- {
- LL_INFOS("Credentials", "Authentication") << "account: " << username << LL_ENDL;
- // single username, so this is a 'clear' identifier
- identifier["type"] = CRED_IDENTIFIER_TYPE_ACCOUNT;
- identifier["account_name"] = username;
-
- if (LLPanelLogin::sInstance->mPasswordModified)
- {
- // password is plaintext
- authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
- authenticator["secret"] = password;
- }
- else
- {
- credential = load_user_credentials(username);
- if (credential.notNull())
- {
- authenticator = credential->getAuthenticator();
- if (authenticator.emptyMap())
- {
- // Likely caused by user trying to log in to non-system grid
- // with unsupported name format, just retry
- LL_WARNS() << "Authenticator failed to load for: " << username << LL_ENDL;
- // password is plaintext
- authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
- authenticator["secret"] = password;
- }
- }
- }
- }
- else
{
// Be lenient in terms of what separators we allow for two-word names
// and allow legacy users to login with firstname.lastname
@@ -773,16 +708,9 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
}
}
credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
- if (!sInstance->mFirstLoginThisInstall)
- {
- remember_psswrd = sInstance->getChild<LLUICtrl>("remember_password")->getValue();
- remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue();
- }
- else
- {
- remember_psswrd = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
- remember_user = remember_psswrd; // on panel_login_first "remember_check" is named as 'remember me'
- }
+
+ remember_psswrd = sInstance->getChild<LLUICtrl>("remember_password")->getValue();
+ remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue();
}
@@ -1145,17 +1073,18 @@ void LLPanelLogin::onUserListCommit(void*)
}
// static
-// At the moment only happens if !mFirstLoginThisInstall
void LLPanelLogin::onRememberUserCheck(void*)
{
- if (sInstance && !sInstance->mFirstLoginThisInstall)
+ if (sInstance)
{
LLCheckBoxCtrl* remember_name(sInstance->getChild<LLCheckBoxCtrl>("remember_name"));
LLCheckBoxCtrl* remember_psswrd(sInstance->getChild<LLCheckBoxCtrl>("remember_password"));
LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo"));
bool remember = remember_name->getValue().asBoolean();
- if (user_combo->getCurrentIndex() != -1 && !remember)
+ if (!sInstance->mFirstLoginThisInstall
+ && user_combo->getCurrentIndex() != -1
+ && !remember)
{
remember = true;
remember_name->setValue(true);
@@ -1169,6 +1098,14 @@ void LLPanelLogin::onRememberUserCheck(void*)
}
}
+void LLPanelLogin::onRememberPasswordCheck(void*)
+{
+ if (sInstance)
+ {
+ gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE);
+ }
+}
+
// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index c5e6b41def..c6254f72cf 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -107,6 +107,7 @@ private:
static void onUserNameTextEnty(void*);
static void onUserListCommit(void*);
static void onRememberUserCheck(void*);
+ static void onRememberPasswordCheck(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void updateServerCombo();
diff --git a/indra/newview/llpanelloginlistener.cpp b/indra/newview/llpanelloginlistener.cpp
index 33efde11f3..fb3e8dc244 100644
--- a/indra/newview/llpanelloginlistener.cpp
+++ b/indra/newview/llpanelloginlistener.cpp
@@ -47,5 +47,5 @@ LLPanelLoginListener::LLPanelLoginListener(LLPanelLogin* instance):
void LLPanelLoginListener::onClickConnect(const LLSD&) const
{
- mPanel->onClickConnect(NULL);
+ mPanel->onClickConnect(false);
}
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 89256b40c4..49562da3f7 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -919,6 +919,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
+ getChild<LLUICtrl>("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL));
getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
@@ -975,6 +976,12 @@ void LLFloaterInventoryFinder::draw()
filtered_by_all_types = FALSE;
}
+ if (!getChild<LLUICtrl>("check_material")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_MATERIAL);
+ filtered_by_all_types = FALSE;
+ }
+
if (!getChild<LLUICtrl>("check_notecard")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
@@ -1129,6 +1136,7 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_material")->setValue(TRUE);
self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
@@ -1149,6 +1157,7 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_material")->setValue(FALSE);
self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
deleted file mode 100644
index 55e4ffff5e..0000000000
--- a/indra/newview/llpanelme.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file llpanelme.cpp
- * @brief Side tray "Me" (My Profile) panel
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelme.h"
-
-// Viewer includes
-#include "llpanelprofile.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "llfirstuse.h"
-#include "llfloaterreg.h"
-#include "llhints.h"
-#include "llviewercontrol.h"
-
-// Linden libraries
-#include "llavatarnamecache.h" // IDEVO
-#include "lliconctrl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h" // IDEVO
-#include "lltabcontainer.h"
-#include "lltexturectrl.h"
-
-static LLPanelInjector<LLPanelMe> t_panel_me_profile("panel_me");
-
-LLPanelMe::LLPanelMe(void)
- : LLPanelProfile()
-{
- setAvatarId(gAgent.getID());
-}
-
-BOOL LLPanelMe::postBuild()
-{
- LLPanelProfile::postBuild();
-
- return TRUE;
-}
-
-void LLPanelMe::onOpen(const LLSD& key)
-{
- LLPanelProfile::onOpen(key);
-}
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 9730f0f16d..e1818cc68b 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -98,9 +98,6 @@ BOOL LLPanelMediaSettingsGeneral::postBuild()
childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this);
- // interrogates controls and updates widgets as required
- updateMediaPreview();
-
return true;
}
@@ -313,9 +310,6 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
-
- // interrogates controls and updates widgets as required
- self->updateMediaPreview();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 831c89b005..0bfc1297d3 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -46,6 +46,7 @@
#include "llcombobox.h"
#include "llfocusmgr.h"
#include "llmanipscale.h"
+#include "llmenubutton.h"
#include "llpreviewscript.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -117,8 +118,9 @@ BOOL LLPanelObject::postBuild()
// Phantom checkbox
mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");
childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
-
+
// Position
+ mMenuClipboardPos = getChild<LLMenuButton>("clipboard_pos_btn");
mLabelPosition = getChild<LLTextBox>("label position");
mCtrlPosX = getChild<LLSpinCtrl>("Pos X");
childSetCommitCallback("Pos X",onCommitPosition,this);
@@ -128,6 +130,7 @@ BOOL LLPanelObject::postBuild()
childSetCommitCallback("Pos Z",onCommitPosition,this);
// Scale
+ mMenuClipboardSize = getChild<LLMenuButton>("clipboard_size_btn");
mLabelSize = getChild<LLTextBox>("label size");
mCtrlScaleX = getChild<LLSpinCtrl>("Scale X");
childSetCommitCallback("Scale X",onCommitScale,this);
@@ -141,6 +144,7 @@ BOOL LLPanelObject::postBuild()
childSetCommitCallback("Scale Z",onCommitScale,this);
// Rotation
+ mMenuClipboardRot = getChild<LLMenuButton>("clipboard_rot_btn");
mLabelRotation = getChild<LLTextBox>("label rotation");
mCtrlRotX = getChild<LLSpinCtrl>("Rot X");
childSetCommitCallback("Rot X",onCommitRotation,this);
@@ -155,6 +159,8 @@ BOOL LLPanelObject::postBuild()
mComboBaseType = getChild<LLComboBox>("comboBaseType");
childSetCommitCallback("comboBaseType",onCommitParametric,this);
+ mMenuClipboardParams = getChild<LLMenuButton>("clipboard_obj_params_btn");
+
// Cut
mLabelCut = getChild<LLTextBox>("text cut");
mSpinCutBegin = getChild<LLSpinCtrl>("cut begin");
@@ -285,8 +291,13 @@ LLPanelObject::LLPanelObject()
mSelectedType(MI_BOX),
mSculptTextureRevert(LLUUID::null),
mSculptTypeRevert(0),
+ mHasClipboardPos(false),
+ mHasClipboardSize(false),
+ mHasClipboardRot(false),
mSizeChanged(FALSE)
{
+ mCommitCallbackRegistrar.add("PanelObject.menuDoToSelected", boost::bind(&LLPanelObject::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelObject.menuEnable", boost::bind(&LLPanelObject::menuEnableItem, this, _2));
}
@@ -373,7 +384,7 @@ void LLPanelObject::getState( )
calcp->clearVar(LLCalc::Z_POS);
}
-
+ mMenuClipboardPos->setEnabled(enable_move);
mLabelPosition->setEnabled( enable_move );
mCtrlPosX->setEnabled(enable_move);
mCtrlPosY->setEnabled(enable_move);
@@ -399,6 +410,7 @@ void LLPanelObject::getState( )
calcp->setVar(LLCalc::Z_SCALE, 0.f);
}
+ mMenuClipboardSize->setEnabled(enable_scale);
mLabelSize->setEnabled( enable_scale );
mCtrlScaleX->setEnabled( enable_scale );
mCtrlScaleY->setEnabled( enable_scale );
@@ -430,6 +442,7 @@ void LLPanelObject::getState( )
calcp->clearVar(LLCalc::Z_ROT);
}
+ mMenuClipboardRot->setEnabled(enable_rotate);
mLabelRotation->setEnabled( enable_rotate );
mCtrlRotX->setEnabled( enable_rotate );
mCtrlRotY->setEnabled( enable_rotate );
@@ -607,7 +620,7 @@ void LLPanelObject::getState( )
}
else
{
- LL_INFOS() << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL;
selected_item = MI_BOX;
}
@@ -933,6 +946,7 @@ void LLPanelObject::getState( )
// Update field enablement
mComboBaseType ->setEnabled( enabled );
+ mMenuClipboardParams->setEnabled(enabled);
mLabelCut ->setEnabled( enabled );
mSpinCutBegin ->setEnabled( enabled );
@@ -1093,7 +1107,8 @@ void LLPanelObject::getState( )
}
mComboBaseType->setEnabled(!isMesh);
-
+ mMenuClipboardParams->setEnabled(!isMesh);
+
if (mCtrlSculptType)
{
if (sculpt_stitching == LL_SCULPT_TYPE_NONE)
@@ -1157,11 +1172,11 @@ void LLPanelObject::sendIsPhysical()
LLSelectMgr::getInstance()->selectionUpdatePhysics(value);
mIsPhysical = value;
- LL_INFOS() << "update physics sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update physics sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update physics not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update physics not changed" << LL_ENDL;
}
}
@@ -1173,11 +1188,11 @@ void LLPanelObject::sendIsTemporary()
LLSelectMgr::getInstance()->selectionUpdateTemporary(value);
mIsTemporary = value;
- LL_INFOS() << "update temporary sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update temporary sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update temporary not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update temporary not changed" << LL_ENDL;
}
}
@@ -1190,11 +1205,11 @@ void LLPanelObject::sendIsPhantom()
LLSelectMgr::getInstance()->selectionUpdatePhantom(value);
mIsPhantom = value;
- LL_INFOS() << "update phantom sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update phantom sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update phantom not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update phantom not changed" << LL_ENDL;
}
}
@@ -1304,7 +1319,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
break;
default:
- LL_WARNS() << "Unknown base type " << selected_type
+ LL_WARNS("FloaterTools") << "Unknown base type " << selected_type
<< " in getVolumeParams()" << LL_ENDL;
// assume a box
selected_type = MI_BOX;
@@ -1644,13 +1659,15 @@ void LLPanelObject::sendPosition(BOOL btn_down)
LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
LLViewerRegion* regionp = mObject->getRegion();
- // Clamp the Z height
- const F32 height = newpos.mV[VZ];
- const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
- const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
+ if (!regionp) return;
if (!mObject->isAttachment())
{
+ // Clamp the Z height
+ const F32 height = newpos.mV[VZ];
+ const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
+ const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
+
if ( height < min_height)
{
newpos.mV[VZ] = min_height;
@@ -1672,8 +1689,19 @@ void LLPanelObject::sendPosition(BOOL btn_down)
// Make sure new position is in a valid region, so the object
// won't get dumped by the simulator.
LLVector3d new_pos_global = regionp->getPosGlobalFromRegion(newpos);
-
- if ( LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global) )
+ bool is_valid_pos = true;
+ if (mObject->isAttachment())
+ {
+ LLVector3 delta_pos = mObject->getPositionEdit() - newpos;
+ LLVector3d attachment_pos = regionp->getPosGlobalFromRegion(mObject->getPositionRegion() + delta_pos);
+ is_valid_pos = LLWorld::getInstance()->positionRegionValidGlobal(attachment_pos);
+ }
+ else
+ {
+ is_valid_pos = LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global);
+ }
+
+ if (is_valid_pos)
{
// send only if the position is changed, that is, the delta vector is not zero
LLVector3d old_pos_global = mObject->getPositionGlobal();
@@ -2000,3 +2028,283 @@ void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
self->sendSculpt();
}
+
+void LLPanelObject::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "psr_paste")
+ {
+ onPastePos();
+ onPasteSize();
+ onPasteRot();
+ }
+ else if (command == "pos_paste")
+ {
+ onPastePos();
+ }
+ else if (command == "size_paste")
+ {
+ onPasteSize();
+ }
+ else if (command == "rot_paste")
+ {
+ onPasteRot();
+ }
+ else if (command == "params_paste")
+ {
+ onPasteParams();
+ }
+ // copy
+ else if (command == "psr_copy")
+ {
+ onCopyPos();
+ onCopySize();
+ onCopyRot();
+ }
+ else if (command == "pos_copy")
+ {
+ onCopyPos();
+ }
+ else if (command == "size_copy")
+ {
+ onCopySize();
+ }
+ else if (command == "rot_copy")
+ {
+ onCopyRot();
+ }
+ else if (command == "params_copy")
+ {
+ onCopyParams();
+ }
+}
+
+bool LLPanelObject::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "psr_paste")
+ {
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME))
+ && (selected_count == 1);
+
+ if (!single_volume)
+ {
+ return false;
+ }
+
+ bool enable_move;
+ bool enable_modify;
+
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify);
+
+ return enable_move && enable_modify && mHasClipboardPos && mHasClipboardSize && mHasClipboardRot;
+ }
+ else if (command == "pos_paste")
+ {
+ // assumes that menu won't be active if there is no move permission
+ return mHasClipboardPos;
+ }
+ else if (command == "size_paste")
+ {
+ return mHasClipboardSize;
+ }
+ else if (command == "rot_paste")
+ {
+ return mHasClipboardRot;
+ }
+ else if (command == "params_paste")
+ {
+ return mClipboardParams.isMap() && !mClipboardParams.emptyMap();
+ }
+ // copy options
+ else if (command == "psr_copy")
+ {
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME))
+ && (selected_count == 1);
+
+ if (!single_volume)
+ {
+ return false;
+ }
+
+ bool enable_move;
+ bool enable_modify;
+
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify);
+
+ // since we forbid seeing values we also should forbid copying them
+ return enable_move && enable_modify;
+ }
+ return false;
+}
+
+void LLPanelObject::onCopyPos()
+{
+ mClipboardPos = LLVector3(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardPos = true;
+}
+
+void LLPanelObject::onCopySize()
+{
+ mClipboardSize = LLVector3(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardSize = true;
+}
+
+void LLPanelObject::onCopyRot()
+{
+ mClipboardRot = LLVector3(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardRot = true;
+}
+
+void LLPanelObject::onPastePos()
+{
+ if (!mHasClipboardPos) return;
+ if (mObject.isNull()) return;
+
+ LLViewerRegion* regionp = mObject->getRegion();
+ if (!regionp) return;
+
+
+ // Clamp pos on non-attachments, just keep the prims within the region
+ if (!mObject->isAttachment())
+ {
+ F32 max_width = regionp->getWidth(); // meters
+ mClipboardPos.mV[VX] = llclamp(mClipboardPos.mV[VX], 0.f, max_width);
+ mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width);
+ //height will get properly clamped by sendPosition
+ }
+
+ mCtrlPosX->set( mClipboardPos.mV[VX] );
+ mCtrlPosY->set( mClipboardPos.mV[VY] );
+ mCtrlPosZ->set( mClipboardPos.mV[VZ] );
+
+ sendPosition(FALSE);
+}
+
+void LLPanelObject::onPasteSize()
+{
+ if (!mHasClipboardSize) return;
+
+ mClipboardSize.mV[VX] = llclamp(mClipboardSize.mV[VX], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+ mClipboardSize.mV[VY] = llclamp(mClipboardSize.mV[VY], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+ mClipboardSize.mV[VZ] = llclamp(mClipboardSize.mV[VZ], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+
+ mCtrlScaleX->set(mClipboardSize.mV[VX]);
+ mCtrlScaleY->set(mClipboardSize.mV[VY]);
+ mCtrlScaleZ->set(mClipboardSize.mV[VZ]);
+
+ sendScale(FALSE);
+}
+
+void LLPanelObject::onPasteRot()
+{
+ if (!mHasClipboardRot) return;
+
+ mCtrlRotX->set(mClipboardRot.mV[VX]);
+ mCtrlRotY->set(mClipboardRot.mV[VY]);
+ mCtrlRotZ->set(mClipboardRot.mV[VZ]);
+
+ sendRotation(FALSE);
+}
+
+void LLPanelObject::onCopyParams()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp || objectp->isMesh())
+ {
+ return;
+ }
+
+ mClipboardParams.clear();
+
+ // Parametrics
+ LLVolumeParams params;
+ getVolumeParams(params);
+ mClipboardParams["volume_params"] = params.asLLSD();
+
+ // Sculpted Prim
+ if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+
+ LLUUID texture_id = sculpt_params->getSculptTexture();
+ if (get_can_copy_texture(texture_id))
+ {
+ LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL;
+ mClipboardParams["sculpt"]["id"] = texture_id;
+ }
+ else
+ {
+ mClipboardParams["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE);
+ }
+
+ mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
+ }
+}
+
+void LLPanelObject::onPasteParams()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ // Sculpted Prim
+ if (mClipboardParams.has("sculpt"))
+ {
+ LLSculptParams sculpt_params;
+ LLUUID sculpt_id = mClipboardParams["sculpt"]["id"].asUUID();
+ U8 sculpt_type = (U8)mClipboardParams["sculpt"]["type"].asInteger();
+ sculpt_params.setSculptTexture(sculpt_id, sculpt_type);
+ objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
+ }
+ else
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ if (sculpt_params)
+ {
+ objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
+ }
+ }
+
+ // volume params
+ // make sure updateVolume() won't affect flexible
+ if (mClipboardParams.has("volume_params"))
+ {
+ LLVolumeParams params;
+ params.fromLLSD(mClipboardParams["volume_params"]);
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ if (volobjp->isFlexible())
+ {
+ if (params.getPathParams().getCurveType() == LL_PCODE_PATH_LINE)
+ {
+ params.getPathParams().setCurveType(LL_PCODE_PATH_FLEXIBLE);
+ }
+ }
+ else if (params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
+ {
+ params.getPathParams().setCurveType(LL_PCODE_PATH_LINE);
+ }
+
+ objectp->updateVolume(params);
+ }
+}
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 8829f493fa..515dd27c0a 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -37,6 +37,7 @@ class LLCheckBoxCtrl;
class LLTextBox;
class LLUICtrl;
class LLButton;
+class LLMenuButton;
class LLViewerObject;
class LLComboBox;
class LLColorSwatchCtrl;
@@ -66,6 +67,14 @@ public:
static void onCommitPhantom( LLUICtrl* ctrl, void* userdata);
static void onCommitPhysics( LLUICtrl* ctrl, void* userdata);
+ void onCopyPos();
+ void onPastePos();
+ void onCopySize();
+ void onPasteSize();
+ void onCopyRot();
+ void onPasteRot();
+ void onCopyParams();
+ void onPasteParams();
static void onCommitParametric(LLUICtrl* ctrl, void* userdata);
@@ -75,6 +84,9 @@ public:
BOOL onDropSculpt(LLInventoryItem* item);
static void onCommitSculptType( LLUICtrl *ctrl, void* userdata);
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
+
protected:
void getState();
@@ -92,6 +104,7 @@ protected:
protected:
// Per-object options
LLComboBox* mComboBaseType;
+ LLMenuButton* mMenuClipboardParams;
LLTextBox* mLabelCut;
LLSpinCtrl* mSpinCutBegin;
@@ -131,17 +144,20 @@ protected:
LLTextBox* mLabelRevolutions;
LLSpinCtrl* mSpinRevolutions;
+ LLMenuButton* mMenuClipboardPos;
LLTextBox* mLabelPosition;
LLSpinCtrl* mCtrlPosX;
LLSpinCtrl* mCtrlPosY;
LLSpinCtrl* mCtrlPosZ;
+ LLMenuButton* mMenuClipboardSize;
LLTextBox* mLabelSize;
LLSpinCtrl* mCtrlScaleX;
LLSpinCtrl* mCtrlScaleY;
LLSpinCtrl* mCtrlScaleZ;
BOOL mSizeChanged;
+ LLMenuButton* mMenuClipboardRot;
LLTextBox* mLabelRotation;
LLSpinCtrl* mCtrlRotX;
LLSpinCtrl* mCtrlRotY;
@@ -157,7 +173,7 @@ protected:
LLComboBox *mCtrlSculptType;
LLCheckBoxCtrl *mCtrlSculptMirror;
LLCheckBoxCtrl *mCtrlSculptInvert;
-
+
LLVector3 mCurEulerDegrees; // to avoid sending rotation when not changed
BOOL mIsPhysical; // to avoid sending "physical" when not changed
BOOL mIsTemporary; // to avoid sending "temporary" when not changed
@@ -167,6 +183,15 @@ protected:
LLUUID mSculptTextureRevert; // so we can revert the sculpt texture on cancel
U8 mSculptTypeRevert; // so we can revert the sculpt type on cancel
+ LLVector3 mClipboardPos;
+ LLVector3 mClipboardSize;
+ LLVector3 mClipboardRot;
+ LLSD mClipboardParams;
+
+ bool mHasClipboardPos;
+ bool mHasClipboardSize;
+ bool mHasClipboardRot;
+
LLPointer<LLViewerObject> mObject;
LLPointer<LLViewerObject> mRootObject;
};
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 0d987df6ca..d61cc26f62 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -50,6 +50,7 @@
#include "llinventoryicon.h"
#include "llinventoryfilter.h"
#include "llinventoryfunctions.h"
+#include "llmaterialeditor.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@@ -618,7 +619,18 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
if (cat)
{
- mDisplayName.assign(cat->getName());
+ std::string name = cat->getName();
+ if (mChildren.size() > 0)
+ {
+ // Add item count
+ // Normally we would be using getLabelSuffix for this
+ // but object's inventory just uses displaynames
+ LLStringUtil::format_map_t args;
+ args["[ITEMS_COUNT]"] = llformat("%d", mChildren.size());
+
+ name.append(" " + LLTrans::getString("InventoryItemsCount", args));
+ }
+ mDisplayName.assign(name);
}
return mDisplayName;
@@ -704,6 +716,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
if(accept && drop)
{
@@ -1151,6 +1164,58 @@ LLSettingsType::type_e LLTaskSettingsBridge::getSettingsType() const
}
///----------------------------------------------------------------------------
+/// Class LLTaskMaterialBridge
+///----------------------------------------------------------------------------
+
+class LLTaskMaterialBridge : public LLTaskInvFVBridge
+{
+public:
+ LLTaskMaterialBridge(LLPanelObjectInventory* panel,
+ const LLUUID& uuid,
+ const std::string& name) :
+ LLTaskInvFVBridge(panel, uuid, name) {}
+
+ BOOL canOpenItem() const override { return TRUE; }
+ void openItem() override;
+ BOOL removeItem() override;
+};
+
+void LLTaskMaterialBridge::openItem()
+{
+ LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
+ if(!object || object->isInventoryPending())
+ {
+ return;
+ }
+
+ // Note: even if we are not allowed to modify copyable notecard, we should be able to view it
+ LLInventoryItem *item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID));
+ BOOL item_copy = item && gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE);
+ if( item_copy
+ || object->permModify()
+ || gAgent.isGodlike())
+ {
+ LLSD floater_key;
+ floater_key["taskid"] = mPanel->getTaskUUID();
+ floater_key["itemid"] = mUUID;
+ LLMaterialEditor* mat = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (mat)
+ {
+ mat->setObjectID(mPanel->getTaskUUID());
+ mat->openFloater(floater_key);
+ mat->setFocus(TRUE);
+ }
+ }
+}
+
+BOOL LLTaskMaterialBridge::removeItem()
+{
+ LLFloaterReg::hideInstance("material_editor", LLSD(mUUID));
+ return LLTaskInvFVBridge::removeItem();
+}
+
+
+///----------------------------------------------------------------------------
/// LLTaskInvFVBridge impl
//----------------------------------------------------------------------------
@@ -1237,6 +1302,11 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
object_name,
itemflags);
break;
+ case LLAssetType::AT_MATERIAL:
+ new_bridge = new LLTaskMaterialBridge(panel,
+ object_id,
+ object_name);
+ break;
default:
LL_INFOS() << "Unhandled inventory type (llassetstorage.h): "
<< (S32)type << LL_ENDL;
@@ -1522,6 +1592,8 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
{
createViewsForCategory(&contents, inventory_root, new_folder);
}
+ // Refresh for label to add item count
+ new_folder->refresh();
}
}
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
deleted file mode 100644
index 40326cfb39..0000000000
--- a/indra/newview/llpanelpick.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/**
- * @file llpanelpick.cpp
- * @brief LLPanelPick class implementation
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpick.h"
-
-#include "message.h"
-
-#include "llparcel.h"
-
-#include "llbutton.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llpanel.h"
-#include "llscrollcontainer.h"
-#include "lltexteditor.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloaterworldmap.h"
-#include "lltexturectrl.h"
-#include "lluiconstants.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include "llworldmap.h"
-
-
-#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
-#define XML_PANEL_PICK_INFO "panel_pick_info.xml"
-
-#define XML_NAME "pick_name"
-#define XML_DESC "pick_desc"
-#define XML_SNAPSHOT "pick_snapshot"
-#define XML_LOCATION "pick_location"
-
-#define XML_BTN_ON_TXTR "edit_icon"
-#define XML_BTN_SAVE "save_changes_btn"
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickInfo* LLPanelPickInfo::create()
-{
- LLPanelPickInfo* panel = new LLPanelPickInfo();
- panel->buildFromFile(XML_PANEL_PICK_INFO);
- return panel;
-}
-
-LLPanelPickInfo::LLPanelPickInfo()
- : LLPanel()
- , LLAvatarPropertiesObserver()
- , LLRemoteParcelInfoObserver()
- , mAvatarId(LLUUID::null)
- , mSnapshotCtrl(NULL)
- , mPickId(LLUUID::null)
- , mParcelId(LLUUID::null)
- , mRequestedId(LLUUID::null)
- , mScrollingPanelMinHeight(0)
- , mScrollingPanelWidth(0)
- , mScrollingPanel(NULL)
- , mScrollContainer(NULL)
-{
-}
-
-LLPanelPickInfo::~LLPanelPickInfo()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::onOpen(const LLSD& key)
-{
- LLUUID avatar_id = key["avatar_id"];
- if(avatar_id.isNull())
- {
- return;
- }
-
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(
- getAvatarId(), this);
- }
-
- setAvatarId(avatar_id);
-
- resetData();
- resetControls();
-
- setPickId(key["pick_id"]);
- setPickName(key["pick_name"]);
- setPickDesc(key["pick_desc"]);
- setSnapshotId(key["snapshot_id"]);
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(
- getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
- getAvatarId(), getPickId());
-}
-
-BOOL LLPanelPickInfo::postBuild()
-{
- mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT);
-
- childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this));
- childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
- childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
-
- mScrollingPanel = getChild<LLPanel>("scroll_content_panel");
- mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
-
- mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
- mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
-
- LLTextEditor* text_desc = getChild<LLTextEditor>(XML_DESC);
- text_desc->setContentTrusted(false);
-
- return TRUE;
-}
-
-void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPanel::reshape(width, height, called_from_parent);
-
- if (!mScrollContainer || !mScrollingPanel)
- return;
-
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- S32 scroll_height = mScrollContainer->getRect().getHeight();
- if (mScrollingPanelMinHeight >= scroll_height)
- {
- mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
- }
- else
- {
- mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
- }
-}
-
-void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICK_INFO != type)
- {
- return;
- }
- LLPickData* pick_info = static_cast<LLPickData*>(data);
- if(!pick_info
- || pick_info->creator_id != getAvatarId()
- || pick_info->pick_id != getPickId())
- {
- return;
- }
-
- mParcelId = pick_info->parcel_id;
- setSnapshotId(pick_info->snapshot_id);
- setPickName(pick_info->name);
- setPickDesc(pick_info->desc);
- setPosGlobal(pick_info->pos_global);
-
- // Send remote parcel info request to get parcel name and sim (region) name.
- sendParcelInfoRequest();
-
- // *NOTE dzaporozhan
- // We want to keep listening to APT_PICK_INFO because user may
- // edit the Pick and we have to update Pick info panel.
- // revomeObserver is called from onClickBack
-}
-
-void LLPanelPickInfo::sendParcelInfoRequest()
-{
- if (mParcelId != mRequestedId)
- {
- LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
- LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
-
- mRequestedId = mParcelId;
- }
-}
-
-void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data)
-{
- setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name,
- parcel_data.sim_name, getPosGlobal()));
-
- // We have received parcel info for the requested ID so clear it now.
- mRequestedId.setNull();
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("edit_btn")->setClickedCallback(cb);
-}
-
-// PROTECTED AREA
-
-void LLPanelPickInfo::resetControls()
-{
- if(getAvatarId() == gAgent.getID())
- {
- getChildView("edit_btn")->setEnabled(TRUE);
- getChildView("edit_btn")->setVisible( TRUE);
- }
- else
- {
- getChildView("edit_btn")->setEnabled(FALSE);
- getChildView("edit_btn")->setVisible( FALSE);
- }
-}
-
-void LLPanelPickInfo::resetData()
-{
- setPickName(LLStringUtil::null);
- setPickDesc(LLStringUtil::null);
- setPickLocation(LLStringUtil::null);
- setPickId(LLUUID::null);
- setSnapshotId(LLUUID::null);
- mPosGlobal.clearVec();
- mParcelId.setNull();
- mRequestedId.setNull();
-}
-
-// static
-std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
-{
- std::string location_text;
- location_text.append(owner_name);
- if (!original_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(original_name);
-
- }
- if (!sim_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(sim_name);
- }
-
- if (!location_text.empty()) location_text.append(" ");
-
- if (!pos_global.isNull())
- {
- S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
- location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
- }
- return location_text;
-}
-
-void LLPanelPickInfo::setSnapshotId(const LLUUID& id)
-{
- mSnapshotCtrl->setImageAssetID(id);
- mSnapshotCtrl->setValid(TRUE);
-}
-
-void LLPanelPickInfo::setPickName(const std::string& name)
-{
- getChild<LLUICtrl>(XML_NAME)->setValue(name);
-}
-
-void LLPanelPickInfo::setPickDesc(const std::string& desc)
-{
- getChild<LLUICtrl>(XML_DESC)->setValue(desc);
-}
-
-void LLPanelPickInfo::setPickLocation(const std::string& location)
-{
- getChild<LLUICtrl>(XML_LOCATION)->setValue(location);
-}
-
-void LLPanelPickInfo::onClickMap()
-{
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-void LLPanelPickInfo::onClickTeleport()
-{
- if (!getPosGlobal().isExactlyZero())
- {
- gAgent.teleportViaLocation(getPosGlobal());
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- }
-}
-
-void LLPanelPickInfo::onClickBack()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickEdit* LLPanelPickEdit::create()
-{
- LLPanelPickEdit* panel = new LLPanelPickEdit();
- panel->buildFromFile(XML_PANEL_EDIT_PICK);
- return panel;
-}
-
-LLPanelPickEdit::LLPanelPickEdit()
- : LLPanelPickInfo()
- , mLocationChanged(false)
- , mNeedData(true)
- , mNewPick(false)
-{
-}
-
-LLPanelPickEdit::~LLPanelPickEdit()
-{
-}
-
-void LLPanelPickEdit::onOpen(const LLSD& key)
-{
- LLUUID pick_id = key["pick_id"];
- mNeedData = true;
-
- // creating new Pick
- if(pick_id.isNull())
- {
- mNewPick = true;
-
- setAvatarId(gAgent.getID());
-
- resetData();
- resetControls();
-
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
- std::string pick_name, pick_desc, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- parcel_id = parcel->getID();
- pick_name = parcel->getName();
- pick_desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setParcelID(parcel_id);
- getChild<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name);
- getChild<LLUICtrl>("pick_desc")->setValue(pick_desc);
- setSnapshotId(snapshot_id);
- setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
-
- enableSaveButton(true);
- }
- // editing existing pick
- else
- {
- mNewPick = false;
- LLPanelPickInfo::onOpen(key);
-
- enableSaveButton(false);
- }
-
- resetDirty();
-}
-
-void LLPanelPickEdit::setPickData(const LLPickData* pick_data)
-{
- if(!pick_data)
- {
- return;
- }
-
- mNeedData = false;
-
- setParcelID(pick_data->parcel_id);
- getChild<LLUICtrl>("pick_name")->setValue(pick_data->name);
- getChild<LLUICtrl>("pick_desc")->setValue(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- setPosGlobal(pick_data->pos_global);
- setPickLocation(createLocationText(LLStringUtil::null, pick_data->name,
- pick_data->sim_name, pick_data->pos_global));
-}
-
-BOOL LLPanelPickEdit::postBuild()
-{
- LLPanelPickInfo::postBuild();
-
- mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this));
-
- LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL);
-
- LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1));
-
- childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this));
-
- initTexturePickerMouseEvents();
-
- return TRUE;
-}
-
-void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("save_changes_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickEdit::resetDirty()
-{
- LLPanelPickInfo::resetDirty();
-
- getChild<LLLineEditor>("pick_name")->resetDirty();
- getChild<LLTextEditor>("pick_desc")->resetDirty();
- mSnapshotCtrl->resetDirty();
- mLocationChanged = false;
-}
-
-BOOL LLPanelPickEdit::isDirty() const
-{
- if( mNewPick
- || LLPanelPickInfo::isDirty()
- || mLocationChanged
- || mSnapshotCtrl->isDirty()
- || getChild<LLLineEditor>("pick_name")->isDirty()
- || getChild<LLTextEditor>("pick_desc")->isDirty())
- {
- return TRUE;
- }
- return FALSE;
-}
-
-// PROTECTED AREA
-
-void LLPanelPickEdit::sendUpdate()
-{
- LLPickData pick_data;
-
- // If we don't have a pick id yet, we'll need to generate one,
- // otherwise we'll keep overwriting pick_id 00000 in the database.
- if (getPickId().isNull())
- {
- getPickId().generate();
- }
-
- pick_data.agent_id = gAgent.getID();
- pick_data.session_id = gAgent.getSessionID();
- pick_data.pick_id = getPickId();
- pick_data.creator_id = gAgent.getID();;
-
- //legacy var need to be deleted
- pick_data.top_pick = FALSE;
- pick_data.parcel_id = mParcelId;
- pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString();
- pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString();
- pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
- pick_data.pos_global = getPosGlobal();
- pick_data.sort_order = 0;
- pick_data.enabled = TRUE;
-
- LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
-
- if(mNewPick)
- {
- // Assume a successful create pick operation, make new number of picks
- // available immediately. Actual number of picks will be requested in
- // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
- LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
- }
-}
-
-void LLPanelPickEdit::onSnapshotChanged()
-{
- enableSaveButton(true);
-}
-
-void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl)
-{
- enableSaveButton(isDirty());
-}
-
-void LLPanelPickEdit::resetData()
-{
- LLPanelPickInfo::resetData();
- mLocationChanged = false;
-}
-
-void LLPanelPickEdit::enableSaveButton(bool enable)
-{
- getChildView(XML_BTN_SAVE)->setEnabled(enable);
-}
-
-void LLPanelPickEdit::onClickSetLocation()
-{
- // Save location for later use.
- setPosGlobal(gAgent.getPositionGlobal());
-
- std::string parcel_name, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (parcel)
- {
- mParcelId = parcel->getID();
- parcel_name = parcel->getName();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
-
- mLocationChanged = true;
- enableSaveButton(TRUE);
-}
-
-void LLPanelPickEdit::onClickSave()
-{
- sendUpdate();
-
- mLocationChanged = false;
-
- LLSD params;
- params["action"] = "save_new_pick";
- notifyParent(params);
-}
-
-std::string LLPanelPickEdit::getLocationNotice()
-{
- static std::string notice = getString("location_notice");
- return notice;
-}
-
-void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(mNeedData)
- {
- LLPanelPickInfo::processProperties(data, type);
- }
-}
-
-// PRIVATE AREA
-
-void LLPanelPickEdit::initTexturePickerMouseEvents()
-{
- text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR);
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1));
-
- text_icon->setVisible(FALSE);
-}
-
-void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- text_icon->setVisible(TRUE);
-}
-
-void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- text_icon->setVisible(FALSE);
-}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
deleted file mode 100644
index 7a8bd66fcf..0000000000
--- a/indra/newview/llpanelpick.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- * @file llpanelpick.h
- * @brief LLPanelPick class definition
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#ifndef LL_LLPANELPICK_H
-#define LL_LLPANELPICK_H
-
-#include "llpanel.h"
-#include "llremoteparcelrequest.h"
-#include "llavatarpropertiesprocessor.h"
-
-class LLIconCtrl;
-class LLTextureCtrl;
-class LLScrollContainer;
-class LLMessageSystem;
-class LLAvatarPropertiesObserver;
-
-/**
- * Panel for displaying Pick Information - snapshot, name, description, etc.
- */
-class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver
-{
- LOG_CLASS(LLPanelPickInfo);
-public:
-
- // Creates new panel
- static LLPanelPickInfo* create();
-
- virtual ~LLPanelPickInfo();
-
- /**
- * Initializes panel properties
- *
- * By default Pick will be created for current Agent location.
- * Use setPickData to change Pick properties.
- */
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /**
- * Sends remote parcel info request to resolve parcel name from its ID.
- */
- void sendParcelInfoRequest();
-
- /**
- * Sets "Back" button click callback
- */
- virtual void setExitCallback(const commit_callback_t& cb);
-
- /**
- * Sets "Edit" button click callback
- */
- virtual void setEditPickCallback(const commit_callback_t& cb);
-
- //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
- /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
- /*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; }
- /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {};
-
-protected:
-
- LLPanelPickInfo();
-
- /**
- * Resets Pick information
- */
- virtual void resetData();
-
- /**
- * Resets UI controls (visibility, values)
- */
- virtual void resetControls();
-
- /**
- * "Location text" is actually the owner name, the original
- * name that owner gave the parcel, and the location.
- */
- static std::string createLocationText(
- const std::string& owner_name,
- const std::string& original_name,
- const std::string& sim_name,
- const LLVector3d& pos_global);
-
- virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
- virtual LLUUID& getAvatarId() { return mAvatarId; }
-
- /**
- * Sets snapshot id.
- *
- * Will mark snapshot control as valid if id is not null.
- * Will mark snapshot control as invalid if id is null. If null id is a valid value,
- * you have to manually mark snapshot is valid.
- */
- virtual void setSnapshotId(const LLUUID& id);
-
- virtual void setPickId(const LLUUID& id) { mPickId = id; }
- virtual LLUUID& getPickId() { return mPickId; }
-
- virtual void setPickName(const std::string& name);
-
- virtual void setPickDesc(const std::string& desc);
-
- virtual void setPickLocation(const std::string& location);
-
- virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
- virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
-
- /**
- * Callback for "Map" button, opens Map
- */
- void onClickMap();
-
- /**
- * Callback for "Teleport" button, teleports user to Pick location.
- */
- void onClickTeleport();
-
- void onClickBack();
-
-protected:
-
- S32 mScrollingPanelMinHeight;
- S32 mScrollingPanelWidth;
- LLScrollContainer* mScrollContainer;
- LLPanel* mScrollingPanel;
- LLTextureCtrl* mSnapshotCtrl;
-
- LLUUID mAvatarId;
- LLVector3d mPosGlobal;
- LLUUID mParcelId;
- LLUUID mPickId;
- LLUUID mRequestedId;
-};
-
-/**
- * Panel for creating/editing Pick.
- */
-class LLPanelPickEdit : public LLPanelPickInfo
-{
- LOG_CLASS(LLPanelPickEdit);
-public:
-
- /**
- * Creates new panel
- */
- static LLPanelPickEdit* create();
-
- /*virtual*/ ~LLPanelPickEdit();
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- virtual void setPickData(const LLPickData* pick_data);
-
- /*virtual*/ BOOL postBuild();
-
- /**
- * Sets "Save" button click callback
- */
- virtual void setSaveCallback(const commit_callback_t& cb);
-
- /**
- * Sets "Cancel" button click callback
- */
- virtual void setCancelCallback(const commit_callback_t& cb);
-
- /**
- * Resets panel and all cantrols to unedited state
- */
- /*virtual*/ void resetDirty();
-
- /**
- * Returns true if any of Pick properties was changed by user.
- */
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
-protected:
-
- LLPanelPickEdit();
-
- /**
- * Sends Pick properties to server.
- */
- void sendUpdate();
-
- /**
- * Called when snapshot image changes.
- */
- void onSnapshotChanged();
-
- /**
- * Callback for Pick snapshot, name and description changed event.
- */
- void onPickChanged(LLUICtrl* ctrl);
-
- /*virtual*/ void resetData();
-
- /**
- * Enables/disables "Save" button
- */
- void enableSaveButton(bool enable);
-
- /**
- * Callback for "Set Location" button click
- */
- void onClickSetLocation();
-
- /**
- * Callback for "Save" button click
- */
- void onClickSave();
-
- std::string getLocationNotice();
-
-protected:
-
- bool mLocationChanged;
- bool mNeedData;
- bool mNewPick;
-
-private:
-
- void initTexturePickerMouseEvents();
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
-private:
-
- LLIconCtrl* text_icon;
-};
-
-#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
deleted file mode 100644
index 8294977f99..0000000000
--- a/indra/newview/llpanelpicks.cpp
+++ /dev/null
@@ -1,1484 +0,0 @@
-/**
- * @file llpanelpicks.cpp
- * @brief LLPanelPicks and related class implementations
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpicks.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llcommandhandler.h"
-#include "lldispatcher.h"
-#include "llflatlistview.h"
-#include "llfloaterreg.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfloaterworldmap.h"
-#include "llnotificationsutil.h"
-#include "llstartup.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
-#include "lltrans.h"
-#include "llviewergenericmessage.h" // send_generic_message
-#include "llmenugl.h"
-#include "llviewermenu.h"
-#include "llregistry.h"
-
-#include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llpanelavatar.h"
-#include "llpanelprofile.h"
-#include "llpanelpick.h"
-#include "llpanelclassified.h"
-
-static const std::string XML_BTN_NEW = "new_btn";
-static const std::string XML_BTN_DELETE = "trash_btn";
-static const std::string XML_BTN_INFO = "info_btn";
-static const std::string XML_BTN_TELEPORT = "teleport_btn";
-static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
-
-static const std::string PICK_ID("pick_id");
-static const std::string PICK_CREATOR_ID("pick_creator_id");
-static const std::string PICK_NAME("pick_name");
-
-static const std::string CLASSIFIED_ID("classified_id");
-static const std::string CLASSIFIED_NAME("classified_name");
-
-
-static LLPanelInjector<LLPanelPicks> t_panel_picks("panel_picks");
-
-
-class LLPickHandler : public LLCommandHandler,
- public LLAvatarPropertiesObserver
-{
-public:
-
- std::set<LLUUID> mPickIds;
-
- // requires trusted browser to trigger
- LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
-
- bool handle(const LLSD& params, const LLSD& query_map,
- LLMediaCtrl* web)
- {
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- return true;
- }
-
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
- {
- LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
- // handle app/classified/create urls first
- if (params.size() == 1 && params[0].asString() == "create")
- {
- createPick();
- return true;
- }
-
- // then handle the general app/pick/{UUID}/{CMD} urls
- if (params.size() < 2)
- {
- return false;
- }
-
- // get the ID for the pick_id
- LLUUID pick_id;
- if (!pick_id.set(params[0], FALSE))
- {
- return false;
- }
-
- // edit the pick in the side tray.
- // need to ask the server for more info first though...
- const std::string verb = params[1].asString();
- if (verb == "edit")
- {
- mPickIds.insert(pick_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(gAgent.getID(),pick_id);
- return true;
- }
- else
- {
- LL_WARNS() << "unknown verb " << verb << LL_ENDL;
- return false;
- }
- }
-
- void createPick()
- {
- // open the new pick panel on the Picks floater
- LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
-
- LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
- if (picks)
- {
- picks->createNewPick();
- }
- }
-
- void editPick(LLPickData* pick_info)
- {
- LLSD params;
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "edit_pick";
- params["pick_id"] = pick_info->pick_id;
- params["avatar_id"] = pick_info->creator_id;
- params["snapshot_id"] = pick_info->snapshot_id;
- params["pick_name"] = pick_info->name;
- params["pick_desc"] = pick_info->desc;
- LLFloaterSidePanelContainer::showPanel("picks", params);
- }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
- {
- if (APT_PICK_INFO != type)
- {
- return;
- }
-
- // is this the pick that we asked for?
- LLPickData* pick_info = static_cast<LLPickData*>(data);
- if (!pick_info || mPickIds.find(pick_info->pick_id) == mPickIds.end())
- {
- return;
- }
-
- // open the edit side tray for this pick
- if (pick_info->creator_id == gAgent.getID())
- {
- editPick(pick_info);
- }
- else
- {
- LL_WARNS() << "Can't edit a pick you did not create" << LL_ENDL;
- }
-
- // remove our observer now that we're done
- mPickIds.erase(pick_info->pick_id);
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
- }
-};
-
-LLPickHandler gPickHandler;
-
-class LLClassifiedHandler :
- public LLCommandHandler,
- public LLAvatarPropertiesObserver
-{
-public:
- // throttle calls from untrusted browsers
- LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
-
- std::set<LLUUID> mClassifiedIds;
-
- std::string mRequestVerb;
-
- bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- return true;
- }
-
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
- {
- LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
- // handle app/classified/create urls first
- if (params.size() == 1 && params[0].asString() == "create")
- {
- createClassified();
- return true;
- }
-
- // then handle the general app/classified/{UUID}/{CMD} urls
- if (params.size() < 2)
- {
- return false;
- }
-
- // get the ID for the classified
- LLUUID classified_id;
- if (!classified_id.set(params[0], FALSE))
- {
- return false;
- }
-
- // show the classified in the side tray.
- // need to ask the server for more info first though...
- const std::string verb = params[1].asString();
- if (verb == "about")
- {
- mRequestVerb = verb;
- mClassifiedIds.insert(classified_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
- return true;
- }
- else if (verb == "edit")
- {
- mRequestVerb = verb;
- mClassifiedIds.insert(classified_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
- return true;
- }
-
- return false;
- }
-
- void createClassified()
- {
- // open the new classified panel on the Picks floater
- LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
-
- LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
- if (picks)
- {
- picks->createNewClassified();
- }
- }
-
- void openClassified(LLAvatarClassifiedInfo* c_info)
- {
- if (mRequestVerb == "about")
- {
- // open the classified info panel on the Me > Picks sidetray
- LLSD params;
- params["id"] = c_info->creator_id;
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "classified_details";
- params["classified_id"] = c_info->classified_id;
- params["classified_creator_id"] = c_info->creator_id;
- params["classified_snapshot_id"] = c_info->snapshot_id;
- params["classified_name"] = c_info->name;
- params["classified_desc"] = c_info->description;
- params["from_search"] = true;
- LLFloaterSidePanelContainer::showPanel("picks", params);
- }
- else if (mRequestVerb == "edit")
- {
- if (c_info->creator_id == gAgent.getID())
- {
- LL_WARNS() << "edit in progress" << LL_ENDL;
- // open the new classified panel on the Me > Picks sidetray
- LLSD params;
- params["id"] = gAgent.getID();
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "edit_classified";
- params["classified_id"] = c_info->classified_id;
- LLFloaterSidePanelContainer::showPanel("my_profile", params);
- }
- else
- {
- LL_WARNS() << "Can't edit a classified you did not create" << LL_ENDL;
- }
- }
- }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
- {
- if (APT_CLASSIFIED_INFO != type)
- {
- return;
- }
-
- // is this the classified that we asked for?
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
- {
- return;
- }
-
- // open the detail side tray for this classified
- openClassified(c_info);
-
- // remove our observer now that we're done
- mClassifiedIds.erase(c_info->classified_id);
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
- }
-
-};
-LLClassifiedHandler gClassifiedHandler;
-
-//////////////////////////////////////////////////////////////////////////
-
-
-//-----------------------------------------------------------------------------
-// LLPanelPicks
-//-----------------------------------------------------------------------------
-LLPanelPicks::LLPanelPicks()
-: LLPanelProfileTab(),
- mPopupMenu(NULL),
- mProfilePanel(NULL),
- mPickPanel(NULL),
- mPicksList(NULL),
- mClassifiedsList(NULL),
- mPanelPickInfo(NULL),
- mPanelPickEdit(NULL),
- mPlusMenu(NULL),
- mPicksAccTab(NULL),
- mClassifiedsAccTab(NULL),
- mPanelClassifiedInfo(NULL),
- mNoClassifieds(false),
- mNoPicks(false)
-{
-}
-
-LLPanelPicks::~LLPanelPicks()
-{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
-}
-
-void* LLPanelPicks::create(void* data /* = NULL */)
-{
- return new LLPanelPicks();
-}
-
-void LLPanelPicks::updateData()
-{
- // Send Picks request only when we need to, not on every onOpen(during tab switch).
- if(isDirty())
- {
- mNoPicks = false;
- mNoClassifieds = false;
-
- mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
- mNoItemsLabel->setVisible(TRUE);
-
- mPicksList->clear();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
-
- mClassifiedsList->clear();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
- }
-}
-
-void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICKS == type)
- {
- LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
- if(avatar_picks && getAvatarId() == avatar_picks->target_id)
- {
- LLAvatarName av_name;
- LLAvatarNameCache::get(getAvatarId(), &av_name);
- getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", av_name.getUserName());
-
- // Save selection, to be able to edit same item after saving changes. See EXT-3023.
- LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
-
- mPicksList->clear();
-
- LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
- for(; avatar_picks->picks_list.end() != it; ++it)
- {
- LLUUID pick_id = it->first;
- std::string pick_name = it->second;
-
- LLPickItem* picture = LLPickItem::create();
- picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
- picture->setPickName(pick_name);
- picture->setPickId(pick_id);
- picture->setCreatorId(getAvatarId());
-
- LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
- picture->update();
-
- LLSD pick_value = LLSD();
- pick_value.insert(PICK_ID, pick_id);
- pick_value.insert(PICK_NAME, pick_name);
- pick_value.insert(PICK_CREATOR_ID, getAvatarId());
-
- mPicksList->addItem(picture, pick_value);
-
- // Restore selection by item id.
- if ( pick_id == selected_id )
- mPicksList->selectItemByValue(pick_value);
-
- picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1));
- picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- }
-
- showAccordion("tab_picks", mPicksList->size());
-
- resetDirty();
- updateButtons();
- }
-
- mNoPicks = !mPicksList->size();
- }
- else if((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
- {
- LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
- if(c_info && getAvatarId() == c_info->target_id)
- {
- // do not clear classified list in case we will receive two or more data packets.
- // list has been cleared in updateData(). (fix for EXT-6436)
-
- LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
- for(; c_info->classifieds_list.end() != it; ++it)
- {
- LLAvatarClassifieds::classified_data c_data = *it;
-
- LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id);
- c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
- c_item->setClassifiedName(c_data.name);
-
- LLSD pick_value = LLSD();
- pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
- pick_value.insert(CLASSIFIED_NAME, c_data.name);
-
- if (!findClassifiedById(c_data.classified_id))
- {
- mClassifiedsList->addItem(c_item, pick_value);
- }
-
- c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
- c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- }
-
- showAccordion("tab_classifieds", mClassifiedsList->size());
-
- resetDirty();
- updateButtons();
- }
-
- mNoClassifieds = !mClassifiedsList->size();
- }
-
- updateNoItemsLabel();
-}
-
-LLPickItem* LLPanelPicks::getSelectedPickItem()
-{
- LLPanel* selected_item = mPicksList->getSelectedItem();
- if (!selected_item) return NULL;
-
- return dynamic_cast<LLPickItem*>(selected_item);
-}
-
-LLClassifiedItem* LLPanelPicks::getSelectedClassifiedItem()
-{
- LLPanel* selected_item = mClassifiedsList->getSelectedItem();
- if (!selected_item)
- {
- return NULL;
- }
- return dynamic_cast<LLClassifiedItem*>(selected_item);
-}
-
-BOOL LLPanelPicks::postBuild()
-{
- mPicksList = getChild<LLFlatListView>("picks_list");
- mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
-
- mPicksList->setCommitOnSelectionChange(true);
- mClassifiedsList->setCommitOnSelectionChange(true);
-
- mPicksList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mPicksList));
- mClassifiedsList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mClassifiedsList));
-
- mPicksList->setNoItemsCommentText(getString("no_picks"));
- mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
-
- mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
-
- childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this));
- childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
- childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this));
- childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this));
- childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this));
-
- mPicksAccTab = getChild<LLAccordionCtrlTab>("tab_picks");
- mPicksAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mPicksAccTab));
- mPicksAccTab->setDisplayChildren(true);
-
- mClassifiedsAccTab = getChild<LLAccordionCtrlTab>("tab_classifieds");
- mClassifiedsAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mClassifiedsAccTab));
- mClassifiedsAccTab->setDisplayChildren(false);
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
- registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
- registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this));
- registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this));
- registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this));
- registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this));
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registar;
- enable_registar.add("Pick.Enable", boost::bind(&LLPanelPicks::onEnableMenuItem, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar;
- plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelPicks::onPlusMenuItemClicked, this, _2));
- mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelPicks::isActionEnabled, this, _2));
- mPlusMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- return TRUE;
-}
-
-void LLPanelPicks::onPlusMenuItemClicked(const LLSD& param)
-{
- std::string value = param.asString();
-
- if("new_pick" == value)
- {
- createNewPick();
- }
- else if("new_classified" == value)
- {
- createNewClassified();
- }
-}
-
-bool LLPanelPicks::isActionEnabled(const LLSD& userdata) const
-{
- std::string command_name = userdata.asString();
-
- if (command_name == "new_pick" && LLAgentPicksInfo::getInstance()->isPickLimitReached())
- {
- return false;
- }
-
- return true;
-}
-
-bool LLPanelPicks::isClassifiedPublished(LLClassifiedItem* c_item)
-{
- if(c_item)
- {
- LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
- if(panel)
- {
- return !panel->isNewWithErrors();
- }
-
- // we've got this classified from server - it's published
- return true;
- }
- return false;
-}
-
-void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab)
-{
- if(!mPicksAccTab->getDisplayChildren())
- {
- mPicksList->resetSelection(true);
- }
- if(!mClassifiedsAccTab->getDisplayChildren())
- {
- mClassifiedsList->resetSelection(true);
- }
-
- updateButtons();
-}
-
-void LLPanelPicks::onOpen(const LLSD& key)
-{
- const LLUUID id(key.asUUID());
- BOOL self = (gAgent.getID() == id);
-
- // only agent can edit her picks
- getChildView("edit_panel")->setEnabled(self);
- getChildView("edit_panel")->setVisible( self);
-
- // Disable buttons when viewing profile for first time
- if(getAvatarId() != id)
- {
- getChildView(XML_BTN_INFO)->setEnabled(FALSE);
- getChildView(XML_BTN_TELEPORT)->setEnabled(FALSE);
- getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(FALSE);
- }
-
- // and see a special title - set as invisible by default in xml file
- if (self)
- {
- getChildView("pick_title")->setVisible( !self);
- getChildView("pick_title_agent")->setVisible( self);
-
- mPopupMenu->setItemVisible("pick_delete", TRUE);
- mPopupMenu->setItemVisible("pick_edit", TRUE);
- mPopupMenu->setItemVisible("pick_separator", TRUE);
- }
-
- if(getAvatarId() != id)
- {
- showAccordion("tab_picks", false);
- showAccordion("tab_classifieds", false);
-
- mPicksList->goToTop();
- // Set dummy value to make panel dirty and make it reload picks
- setValue(LLSD());
- }
-
- LLPanelProfileTab::onOpen(key);
-}
-
-void LLPanelPicks::onClosePanel()
-{
- if (mPanelClassifiedInfo)
- {
- onPanelClassifiedClose(mPanelClassifiedInfo);
- }
- if (mPanelPickInfo)
- {
- onPanelPickClose(mPanelPickInfo);
- }
-}
-
-void LLPanelPicks::onListCommit(const LLFlatListView* f_list)
-{
- // Make sure only one of the lists has selection.
- if(f_list == mPicksList)
- {
- mClassifiedsList->resetSelection(true);
- }
- else if(f_list == mClassifiedsList)
- {
- mPicksList->resetSelection(true);
- }
- else
- {
- LL_WARNS() << "Unknown list" << LL_ENDL;
- }
-
- updateButtons();
-}
-
-//static
-void LLPanelPicks::onClickDelete()
-{
- LLSD value = mPicksList->getSelectedValue();
- if (value.isDefined())
- {
- LLSD args;
- args["PICK"] = value[PICK_NAME];
- LLNotificationsUtil::add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeletePick, this, _1, _2));
- return;
- }
-
- value = mClassifiedsList->getSelectedValue();
- if(value.isDefined())
- {
- LLSD args;
- args["NAME"] = value[CLASSIFIED_NAME];
- LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeleteClassified, this, _1, _2));
- return;
- }
-}
-
-bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLSD pick_value = mPicksList->getSelectedValue();
-
- if (0 == option)
- {
- LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
- mPicksList->removeItemByValue(pick_value);
-
- mNoPicks = !mPicksList->size();
- if (mNoPicks)
- {
- showAccordion("tab_picks", false);
- }
- updateNoItemsLabel();
- }
- updateButtons();
- return false;
-}
-
-bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLSD value = mClassifiedsList->getSelectedValue();
-
- if (0 == option)
- {
- LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
- mClassifiedsList->removeItemByValue(value);
-
- mNoClassifieds = !mClassifiedsList->size();
- if (mNoClassifieds)
- {
- showAccordion("tab_classifieds", false);
- }
- updateNoItemsLabel();
- }
- updateButtons();
- return false;
-}
-
-bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- if (0 == option)
- {
- onClickTeleport();
- }
- return false;
-}
-
-//static
-void LLPanelPicks::onClickTeleport()
-{
- LLPickItem* pick_item = getSelectedPickItem();
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
-
- LLVector3d pos;
- if(pick_item)
- pos = pick_item->getPosGlobal();
- else if(c_item)
- {
- pos = c_item->getPosGlobal();
- LLPanelClassifiedInfo::sendClickMessage("teleport", false,
- c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
- }
-
- if (!pos.isExactlyZero())
- {
- gAgent.teleportViaLocation(pos);
- LLFloaterWorldMap::getInstance()->trackLocation(pos);
- }
-}
-
-//static
-void LLPanelPicks::onClickMap()
-{
- LLPickItem* pick_item = getSelectedPickItem();
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
-
- LLVector3d pos;
- if (pick_item)
- pos = pick_item->getPosGlobal();
- else if(c_item)
- {
- LLPanelClassifiedInfo::sendClickMessage("map", false,
- c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
- pos = c_item->getPosGlobal();
- }
-
- LLFloaterWorldMap::getInstance()->trackLocation(pos);
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-
-void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
-{
- updateButtons();
-
- if (mPopupMenu)
- {
- mPopupMenu->buildDrawLabels();
- mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- ((LLContextMenu*)mPopupMenu)->show(x, y);
- LLMenuGL::showPopup(item, mPopupMenu, x, y);
- }
-}
-
-void LLPanelPicks::onDoubleClickPickItem(LLUICtrl* item)
-{
- LLSD pick_value = mPicksList->getSelectedValue();
- if (pick_value.isUndefined()) return;
-
- LLSD args;
- args["PICK"] = pick_value[PICK_NAME];
- LLNotificationsUtil::add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
-}
-
-void LLPanelPicks::onDoubleClickClassifiedItem(LLUICtrl* item)
-{
- LLSD value = mClassifiedsList->getSelectedValue();
- if (value.isUndefined()) return;
-
- LLSD args;
- args["CLASSIFIED"] = value[CLASSIFIED_NAME];
- LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
-}
-
-void LLPanelPicks::updateButtons()
-{
- bool has_selected = mPicksList->numSelected() > 0 || mClassifiedsList->numSelected() > 0;
-
- if (getAvatarId() == gAgentID)
- {
- getChildView(XML_BTN_DELETE)->setEnabled(has_selected);
- }
-
- getChildView(XML_BTN_INFO)->setEnabled(has_selected);
- getChildView(XML_BTN_TELEPORT)->setEnabled(has_selected);
- getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(has_selected);
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- if(c_item)
- {
- getChildView(XML_BTN_INFO)->setEnabled(isClassifiedPublished(c_item));
- }
-}
-
-void LLPanelPicks::updateNoItemsLabel()
-{
- bool no_data = mNoPicks && mNoClassifieds;
- mNoItemsLabel->setVisible(no_data);
- if (no_data)
- {
- if (getAvatarId() == gAgentID)
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
- }
- else
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
- }
- }
-}
-
-void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
-{
- mProfilePanel = profile_panel;
-}
-
-
-void LLPanelPicks::buildPickPanel()
-{
-// if (mPickPanel == NULL)
-// {
-// mPickPanel = new LLPanelPick();
-// mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, NULL));
-// }
-}
-
-void LLPanelPicks::onClickPlusBtn()
-{
- LLRect rect(getChildView(XML_BTN_NEW)->getRect());
-
- mPlusMenu->updateParent(LLMenuGL::sMenuContainer);
- mPlusMenu->setButtonRect(rect, this);
- LLMenuGL::showPopup(this, mPlusMenu, rect.mLeft, rect.mTop);
-}
-
-void LLPanelPicks::createNewPick()
-{
- createPickEditPanel();
-
- getProfilePanel()->openPanel(mPanelPickEdit, LLSD());
-}
-
-void LLPanelPicks::createNewClassified()
-{
- LLPanelClassifiedEdit* panel = NULL;
- createClassifiedEditPanel(&panel);
-
- getProfilePanel()->openPanel(panel, LLSD());
-}
-
-void LLPanelPicks::onClickInfo()
-{
- if(mPicksList->numSelected() > 0)
- {
- openPickInfo();
- }
- else if(mClassifiedsList->numSelected() > 0)
- {
- openClassifiedInfo();
- }
-}
-
-void LLPanelPicks::openPickInfo()
-{
- LLSD selected_value = mPicksList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLPickItem* pick = (LLPickItem*)mPicksList->getSelectedItem();
-
- createPickInfoPanel();
-
- LLSD params;
- params["pick_id"] = pick->getPickId();
- params["avatar_id"] = pick->getCreatorId();
- params["snapshot_id"] = pick->getSnapshotId();
- params["pick_name"] = pick->getPickName();
- params["pick_desc"] = pick->getPickDesc();
-
- getProfilePanel()->openPanel(mPanelPickInfo, params);
-}
-
-void LLPanelPicks::openClassifiedInfo()
-{
- LLSD selected_value = mClassifiedsList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
- LLSD params;
- params["classified_id"] = c_item->getClassifiedId();
- params["classified_creator_id"] = c_item->getAvatarId();
- params["classified_snapshot_id"] = c_item->getSnapshotId();
- params["classified_name"] = c_item->getClassifiedName();
- params["classified_desc"] = c_item->getDescription();
- params["from_search"] = false;
-
- openClassifiedInfo(params);
-}
-
-void LLPanelPicks::openClassifiedInfo(const LLSD &params)
-{
- createClassifiedInfoPanel();
- getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
-}
-
-void LLPanelPicks::openClassifiedEdit(const LLSD& params)
-{
- LLUUID classified_id = params["classified_id"].asUUID();;
- LL_INFOS() << "opening classified " << classified_id << " for edit" << LL_ENDL;
- editClassified(classified_id);
-}
-
-void LLPanelPicks::showAccordion(const std::string& name, bool show)
-{
- LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name);
- tab->setVisible(show);
- LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion");
- acc->arrange();
-}
-
-void LLPanelPicks::onPanelPickClose(LLPanel* panel)
-{
- getProfilePanel()->closePanel(panel);
-}
-
-void LLPanelPicks::onPanelPickSave(LLPanel* panel)
-{
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel)
-{
- if(!panel->canClose())
- {
- return;
- }
-
- if(panel->isNew())
- {
- mEditClassifiedPanels[panel->getClassifiedId()] = panel;
-
- LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId());
- c_item->fillIn(panel);
-
- LLSD c_value;
- c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
- c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
- mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
-
- c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
- c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
-
- // order does matter, showAccordion will invoke arrange for accordions.
- mClassifiedsAccTab->changeOpenClose(false);
- showAccordion("tab_classifieds", true);
- }
- else if(panel->isNewWithErrors())
- {
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- llassert(c_item);
- if (c_item)
- {
- c_item->fillIn(panel);
- }
- }
- else
- {
- onPanelClassifiedClose(panel);
- return;
- }
-
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel)
-{
- if(panel->getInfoLoaded() && !panel->isDirty())
- {
- std::vector<LLSD> values;
- mClassifiedsList->getValues(values);
- for(size_t n = 0; n < values.size(); ++n)
- {
- LLUUID c_id = values[n][CLASSIFIED_ID].asUUID();
- if(panel->getClassifiedId() == c_id)
- {
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(
- mClassifiedsList->getItemByValue(values[n]));
- llassert(c_item);
- if (c_item)
- {
- c_item->setClassifiedName(panel->getClassifiedName());
- c_item->setDescription(panel->getDescription());
- c_item->setSnapshotId(panel->getSnapshotId());
- }
- }
- }
- }
-
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::createPickInfoPanel()
-{
- if(!mPanelPickInfo)
- {
- mPanelPickInfo = LLPanelPickInfo::create();
- mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
- mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
- mPanelPickInfo->setVisible(FALSE);
- }
-}
-
-void LLPanelPicks::createClassifiedInfoPanel()
-{
- mPanelClassifiedInfo = LLPanelClassifiedInfo::create();
- mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo));
- mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this));
- mPanelClassifiedInfo->setVisible(FALSE);
-}
-
-void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel)
-{
- if(panel)
- {
- LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create();
- new_panel->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
- new_panel->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, new_panel));
- new_panel->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
- new_panel->setVisible(FALSE);
- *panel = new_panel;
- }
-}
-
-void LLPanelPicks::createPickEditPanel()
-{
- mPanelPickEdit = LLPanelPickEdit::create();
- mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit));
- mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setVisible(FALSE);
-}
-
-// void LLPanelPicks::openPickEditPanel(LLPickItem* pick)
-// {
-// if(!pick)
-// {
-// return;
-// }
-// }
-
-// void LLPanelPicks::openPickInfoPanel(LLPickItem* pick)
-// {
-// if(!mPanelPickInfo)
-// {
-// mPanelPickInfo = LLPanelPickInfo::create();
-// mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
-// mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
-// mPanelPickInfo->setVisible(FALSE);
-// }
-//
-// LLSD params;
-// params["pick_id"] = pick->getPickId();
-// params["avatar_id"] = pick->getCreatorId();
-// params["snapshot_id"] = pick->getSnapshotId();
-// params["pick_name"] = pick->getPickName();
-// params["pick_desc"] = pick->getPickDesc();
-//
-// getProfilePanel()->openPanel(mPanelPickInfo, params);
-// }
-
-void LLPanelPicks::openPickEdit(const LLSD& params)
-{
- createPickEditPanel();
- getProfilePanel()->openPanel(mPanelPickEdit, params);
-}
-
-void LLPanelPicks::onPanelPickEdit()
-{
- LLSD selected_value = mPicksList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem());
-
- createPickEditPanel();
-
- LLSD params;
- params["pick_id"] = pick->getPickId();
- params["avatar_id"] = pick->getCreatorId();
- params["snapshot_id"] = pick->getSnapshotId();
- params["pick_name"] = pick->getPickName();
- params["pick_desc"] = pick->getPickDesc();
-
- getProfilePanel()->openPanel(mPanelPickEdit, params);
-}
-
-void LLPanelPicks::onPanelClassifiedEdit()
-{
- LLSD selected_value = mClassifiedsList->getSelectedValue();
- if (selected_value.isUndefined())
- {
- return;
- }
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- llassert(c_item);
- if (!c_item)
- {
- return;
- }
- editClassified(c_item->getClassifiedId());
-}
-
-LLClassifiedItem *LLPanelPicks::findClassifiedById(const LLUUID& classified_id)
-{
- // HACK - find item by classified id. Should be a better way.
- std::vector<LLPanel*> items;
- mClassifiedsList->getItems(items);
- LLClassifiedItem* c_item = NULL;
- for(std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
- {
- LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(*it);
- if (test_item && test_item->getClassifiedId() == classified_id)
- {
- c_item = test_item;
- break;
- }
- }
- return c_item;
-}
-
-void LLPanelPicks::editClassified(const LLUUID& classified_id)
-{
- LLClassifiedItem* c_item = findClassifiedById(classified_id);
- if (!c_item)
- {
- LL_WARNS() << "item not found for classified_id " << classified_id << LL_ENDL;
- return;
- }
-
- LLSD params;
- params["classified_id"] = c_item->getClassifiedId();
- params["classified_creator_id"] = c_item->getAvatarId();
- params["snapshot_id"] = c_item->getSnapshotId();
- params["name"] = c_item->getClassifiedName();
- params["desc"] = c_item->getDescription();
- params["category"] = (S32)c_item->getCategory();
- params["content_type"] = (S32)c_item->getContentType();
- params["auto_renew"] = c_item->getAutoRenew();
- params["price_for_listing"] = c_item->getPriceForListing();
- params["location_text"] = c_item->getLocationText();
-
- LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
- if(!panel)
- {
- createClassifiedEditPanel(&panel);
- mEditClassifiedPanels[c_item->getClassifiedId()] = panel;
- }
- getProfilePanel()->openPanel(panel, params);
- panel->setPosGlobal(c_item->getPosGlobal());
-}
-
-void LLPanelPicks::onClickMenuEdit()
-{
- if(getSelectedPickItem())
- {
- onPanelPickEdit();
- }
- else if(getSelectedClassifiedItem())
- {
- onPanelClassifiedEdit();
- }
-}
-
-bool LLPanelPicks::onEnableMenuItem(const LLSD& user_data)
-{
- std::string param = user_data.asString();
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- if(c_item && "info" == param)
- {
- // dont show Info panel if classified was not created
- return isClassifiedPublished(c_item);
- }
-
- return true;
-}
-
-inline LLPanelProfile* LLPanelPicks::getProfilePanel()
-{
- llassert_always(NULL != mProfilePanel);
- return mProfilePanel;
-}
-
-//-----------------------------------------------------------------------------
-// LLPanelPicks
-//-----------------------------------------------------------------------------
-LLPickItem::LLPickItem()
-: LLPanel()
-, mPickID(LLUUID::null)
-, mCreatorID(LLUUID::null)
-, mParcelID(LLUUID::null)
-, mSnapshotID(LLUUID::null)
-, mNeedData(true)
-{
- buildFromFile("panel_pick_list_item.xml");
-}
-
-LLPickItem::~LLPickItem()
-{
- if (mCreatorID.notNull())
- {
- LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
- }
-
-}
-
-LLPickItem* LLPickItem::create()
-{
- return new LLPickItem();
-}
-
-void LLPickItem::init(LLPickData* pick_data)
-{
- setPickDesc(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- mPosGlobal = pick_data->pos_global;
- mSimName = pick_data->sim_name;
- mPickDescription = pick_data->desc;
- mUserName = pick_data->user_name;
- mOriginalName = pick_data->original_name;
-
- LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
- picture->setImageAssetID(pick_data->snapshot_id);
-}
-
-void LLPickItem::setPickName(const std::string& name)
-{
- mPickName = name;
- getChild<LLUICtrl>("picture_name")->setValue(name);
-
-}
-
-const std::string& LLPickItem::getPickName()
-{
- return mPickName;
-}
-
-const LLUUID& LLPickItem::getCreatorId()
-{
- return mCreatorID;
-}
-
-const LLUUID& LLPickItem::getSnapshotId()
-{
- return mSnapshotID;
-}
-
-void LLPickItem::setPickDesc(const std::string& descr)
-{
- getChild<LLUICtrl>("picture_descr")->setValue(descr);
-}
-
-void LLPickItem::setPickId(const LLUUID& id)
-{
- mPickID = id;
-}
-
-const LLUUID& LLPickItem::getPickId()
-{
- return mPickID;
-}
-
-const LLVector3d& LLPickItem::getPosGlobal()
-{
- return mPosGlobal;
-}
-
-const std::string LLPickItem::getDescription()
-{
- return getChild<LLUICtrl>("picture_descr")->getValue().asString();
-}
-
-void LLPickItem::update()
-{
- setNeedData(true);
- LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID);
-}
-
-void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
-{
- if (APT_PICK_INFO != type)
- {
- return;
- }
-
- LLPickData* pick_data = static_cast<LLPickData *>(data);
- if (!pick_data || mPickID != pick_data->pick_id)
- {
- return;
- }
-
- init(pick_data);
- setNeedData(false);
- LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
-}
-
-void set_child_visible(LLView* parent, const std::string& child_name, bool visible)
-{
- parent->getChildView(child_name)->setVisible(visible);
-}
-
-BOOL LLPickItem::postBuild()
-{
- setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
- setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
- return TRUE;
-}
-
-void LLPickItem::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;;
- if (!value.has("selected")) return;
- getChildView("selected_icon")->setVisible( value["selected"]);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
- : LLPanel()
- , mAvatarId(avatar_id)
- , mClassifiedId(classified_id)
-{
- buildFromFile("panel_classifieds_list_item.xml");
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
-}
-
-LLClassifiedItem::~LLClassifiedItem()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO != type)
- {
- return;
- }
-
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if( !c_info || c_info->classified_id != getClassifiedId() )
- {
- return;
- }
-
- setClassifiedName(c_info->name);
- setDescription(c_info->description);
- setSnapshotId(c_info->snapshot_id);
- setPosGlobal(c_info->pos_global);
-
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-BOOL LLClassifiedItem::postBuild()
-{
- setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
- setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
- return TRUE;
-}
-
-void LLClassifiedItem::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;;
- if (!value.has("selected")) return;
- getChildView("selected_icon")->setVisible( value["selected"]);
-}
-
-void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel)
-{
- if(!panel)
- {
- return;
- }
-
- setClassifiedName(panel->getClassifiedName());
- setDescription(panel->getDescription());
- setSnapshotId(panel->getSnapshotId());
- setCategory(panel->getCategory());
- setContentType(panel->getContentType());
- setAutoRenew(panel->getAutoRenew());
- setPriceForListing(panel->getPriceForListing());
- setPosGlobal(panel->getPosGlobal());
- setLocationText(panel->getClassifiedLocation());
-}
-
-void LLClassifiedItem::setClassifiedName(const std::string& name)
-{
- getChild<LLUICtrl>("name")->setValue(name);
-}
-
-void LLClassifiedItem::setDescription(const std::string& desc)
-{
- getChild<LLUICtrl>("description")->setValue(desc);
-}
-
-void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
-{
- getChild<LLUICtrl>("picture")->setValue(snapshot_id);
-}
-
-LLUUID LLClassifiedItem::getSnapshotId()
-{
- return getChild<LLUICtrl>("picture")->getValue();
-}
-
-//EOF
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
deleted file mode 100644
index fd7688b99d..0000000000
--- a/indra/newview/llpanelpicks.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
- * @file llpanelpicks.h
- * @brief LLPanelPicks and related class definitions
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLPANELPICKS_H
-#define LL_LLPANELPICKS_H
-
-#include "llpanel.h"
-#include "v3dmath.h"
-#include "lluuid.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llpanelavatar.h"
-#include "llregistry.h"
-
-class LLAccordionCtrlTab;
-class LLPanelProfile;
-class LLMessageSystem;
-class LLVector3d;
-class LLPanelProfileTab;
-class LLAgent;
-class LLMenuGL;
-class LLPickItem;
-class LLClassifiedItem;
-class LLFlatListView;
-class LLPanelPickInfo;
-class LLPanelPickEdit;
-class LLToggleableMenu;
-class LLPanelClassifiedInfo;
-class LLPanelClassifiedEdit;
-
-// *TODO
-// Panel Picks has been consolidated with Classifieds (EXT-2095), give LLPanelPicks
-// and corresponding files (cpp, h, xml) a new name. (new name is TBD at the moment)
-
-class LLPanelPicks
- : public LLPanelProfileTab
-{
-public:
- LLPanelPicks();
- ~LLPanelPicks();
-
- static void* create(void* data);
-
- /*virtual*/ BOOL postBuild(void);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void onClosePanel();
-
- void processProperties(void* data, EAvatarProcessorType type);
-
- void updateData();
-
- // returns the selected pick item
- LLPickItem* getSelectedPickItem();
- LLClassifiedItem* getSelectedClassifiedItem();
- LLClassifiedItem* findClassifiedById(const LLUUID& classified_id);
-
- //*NOTE top down approch when panel toggling is done only by
- // parent panels failed to work (picks related code was in my profile panel)
- void setProfilePanel(LLPanelProfile* profile_panel);
-
- void createNewPick();
- void createNewClassified();
-
-protected:
- /*virtual*/void updateButtons();
- void updateNoItemsLabel();
-
-private:
- void onClickDelete();
- void onClickTeleport();
- void onClickMap();
-
- void onPlusMenuItemClicked(const LLSD& param);
- bool isActionEnabled(const LLSD& userdata) const;
-
- bool isClassifiedPublished(LLClassifiedItem* c_item);
-
- void onListCommit(const LLFlatListView* f_list);
- void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab);
-
- //------------------------------------------------
- // Callbacks which require panel toggling
- //------------------------------------------------
- void onClickPlusBtn();
- void onClickInfo();
- void onPanelPickClose(LLPanel* panel);
- void onPanelPickSave(LLPanel* panel);
- void onPanelClassifiedSave(LLPanelClassifiedEdit* panel);
- void onPanelClassifiedClose(LLPanelClassifiedInfo* panel);
- void openPickEdit(const LLSD& params);
- void onPanelPickEdit();
- void onPanelClassifiedEdit();
- void editClassified(const LLUUID& classified_id);
- void onClickMenuEdit();
-
- bool onEnableMenuItem(const LLSD& user_data);
-
- void openPickInfo();
- void openClassifiedInfo();
- void openClassifiedInfo(const LLSD& params);
- void openClassifiedEdit(const LLSD& params);
- friend class LLPanelProfile;
-
- void showAccordion(const std::string& name, bool show);
-
- void buildPickPanel();
-
- bool callbackDeletePick(const LLSD& notification, const LLSD& response);
- bool callbackDeleteClassified(const LLSD& notification, const LLSD& response);
- bool callbackTeleport(const LLSD& notification, const LLSD& response);
-
-
- virtual void onDoubleClickPickItem(LLUICtrl* item);
- virtual void onDoubleClickClassifiedItem(LLUICtrl* item);
- virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
-
- LLPanelProfile* getProfilePanel();
-
- void createPickInfoPanel();
- void createPickEditPanel();
- void createClassifiedInfoPanel();
- void createClassifiedEditPanel(LLPanelClassifiedEdit** panel);
-
- LLMenuGL* mPopupMenu;
- LLPanelProfile* mProfilePanel;
- LLPanelPickInfo* mPickPanel;
- LLFlatListView* mPicksList;
- LLFlatListView* mClassifiedsList;
- LLPanelPickInfo* mPanelPickInfo;
- LLPanelClassifiedInfo* mPanelClassifiedInfo;
- LLPanelPickEdit* mPanelPickEdit;
- LLToggleableMenu* mPlusMenu;
- LLUICtrl* mNoItemsLabel;
-
- // <classified_id, edit_panel>
- typedef std::map<LLUUID, LLPanelClassifiedEdit*> panel_classified_edit_map_t;
-
- // This map is needed for newly created classifieds. The purpose of panel is to
- // sit in this map and listen to LLPanelClassifiedEdit::processProperties callback.
- panel_classified_edit_map_t mEditClassifiedPanels;
-
- LLAccordionCtrlTab* mPicksAccTab;
- LLAccordionCtrlTab* mClassifiedsAccTab;
-
- //true if picks list is empty after processing picks
- bool mNoPicks;
- //true if classifieds list is empty after processing classifieds
- bool mNoClassifieds;
-};
-
-class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
-{
-public:
-
- LLPickItem();
-
- static LLPickItem* create();
-
- void init(LLPickData* pick_data);
-
- void setPickName(const std::string& name);
-
- void setPickDesc(const std::string& descr);
-
- void setPickId(const LLUUID& id);
-
- void setCreatorId(const LLUUID& id) {mCreatorID = id;};
-
- void setSnapshotId(const LLUUID& id) {mSnapshotID = id;};
-
- void setNeedData(bool need){mNeedData = need;};
-
- const LLUUID& getPickId();
-
- const std::string& getPickName();
-
- const LLUUID& getCreatorId();
-
- const LLUUID& getSnapshotId();
-
- const LLVector3d& getPosGlobal();
-
- const std::string getDescription();
-
- const std::string& getSimName() { return mSimName; }
-
- const std::string& getUserName() { return mUserName; }
-
- const std::string& getOriginalName() { return mOriginalName; }
-
- const std::string& getPickDesc() { return mPickDescription; }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- void update();
-
- ~LLPickItem();
-
- /*virtual*/ BOOL postBuild();
-
- /** setting on/off background icon to indicate selected state */
- /*virtual*/ void setValue(const LLSD& value);
-
-protected:
-
- LLUUID mPickID;
- LLUUID mCreatorID;
- LLUUID mParcelID;
- LLUUID mSnapshotID;
- LLVector3d mPosGlobal;
- bool mNeedData;
-
- std::string mPickName;
- std::string mUserName;
- std::string mOriginalName;
- std::string mPickDescription;
- std::string mSimName;
-};
-
-class LLClassifiedItem : public LLPanel, public LLAvatarPropertiesObserver
-{
-public:
-
- LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id);
-
- virtual ~LLClassifiedItem();
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setValue(const LLSD& value);
-
- void fillIn(LLPanelClassifiedEdit* panel);
-
- LLUUID getAvatarId() {return mAvatarId;}
-
- void setAvatarId(const LLUUID& avatar_id) {mAvatarId = avatar_id;}
-
- LLUUID getClassifiedId() {return mClassifiedId;}
-
- void setClassifiedId(const LLUUID& classified_id) {mClassifiedId = classified_id;}
-
- void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
-
- const LLVector3d getPosGlobal() { return mPosGlobal; }
-
- void setLocationText(const std::string location) { mLocationText = location; }
-
- std::string getLocationText() { return mLocationText; }
-
- void setClassifiedName (const std::string& name);
-
- std::string getClassifiedName() { return getChild<LLUICtrl>("name")->getValue().asString(); }
-
- void setDescription(const std::string& desc);
-
- std::string getDescription() { return getChild<LLUICtrl>("description")->getValue().asString(); }
-
- void setSnapshotId(const LLUUID& snapshot_id);
-
- LLUUID getSnapshotId();
-
- void setCategory(U32 cat) { mCategory = cat; }
-
- U32 getCategory() { return mCategory; }
-
- void setContentType(U32 ct) { mContentType = ct; }
-
- U32 getContentType() { return mContentType; }
-
- void setAutoRenew(U32 renew) { mAutoRenew = renew; }
-
- bool getAutoRenew() { return mAutoRenew; }
-
- void setPriceForListing(S32 price) { mPriceForListing = price; }
-
- S32 getPriceForListing() { return mPriceForListing; }
-
-private:
- LLUUID mAvatarId;
- LLUUID mClassifiedId;
- LLVector3d mPosGlobal;
- std::string mLocationText;
- U32 mCategory;
- U32 mContentType;
- bool mAutoRenew;
- S32 mPriceForListing;
-};
-
-#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 9157df789f..fb5957ff8f 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -27,6 +27,8 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelplaceinfo.h"
+#include "llfloaterprofile.h"
+#include "llfloaterreg.h"
#include "llavatarname.h"
#include "llsdutil.h"
@@ -42,7 +44,6 @@
#include "llagent.h"
#include "llexpandabletextbox.h"
-#include "llpanelpick.h"
#include "llslurl.h"
#include "lltexturectrl.h"
#include "llviewerregion.h"
@@ -287,7 +288,7 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
}
}
-void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
+void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global)
{
LLPickData data;
data.pos_global = pos_global;
@@ -296,7 +297,12 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit*
data.desc = mDescEditor->getText();
data.snapshot_id = mSnapshotCtrl->getImageAssetID();
data.parcel_id = mParcelID;
- pick_panel->setPickData(&data);
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
// static
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 8bf67cfe7d..533215016a 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -38,7 +38,6 @@ class LLAvatarName;
class LLExpandableTextBox;
class LLIconCtrl;
class LLInventoryItem;
-class LLPanelPickEdit;
class LLParcel;
class LLScrollContainer;
class LLTextBox;
@@ -94,7 +93,7 @@ public:
// Create a pick for the location specified
// by global_pos.
- void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel);
+ void createPick(const LLVector3d& pos_global);
protected:
static void onNameCache(LLTextBox* text, const std::string& full_name);
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 69f181e1b3..74ec576554 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -63,7 +63,6 @@
#include "lllayoutstack.h"
#include "llpanellandmarkinfo.h"
#include "llpanellandmarks.h"
-#include "llpanelpick.h"
#include "llpanelplaceprofile.h"
#include "llpanelteleporthistory.h"
#include "llremoteparcelrequest.h"
@@ -238,7 +237,6 @@ LLPanelPlaces::LLPanelPlaces()
mFilterEditor(NULL),
mPlaceProfile(NULL),
mLandmarkInfo(NULL),
- mPickPanel(NULL),
mItem(NULL),
mPlaceMenu(NULL),
mLandmarkMenu(NULL),
@@ -952,28 +950,11 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
}
else if (item == "pick")
{
- if (mPickPanel == NULL)
- {
- mPickPanel = LLPanelPickEdit::create();
- addChild(mPickPanel);
-
- mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- mPickPanel->setCancelCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- mPickPanel->setSaveCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- }
-
- togglePickPanel(TRUE);
- mPickPanel->onOpen(LLSD());
-
LLPanelPlaceInfo* panel = getCurrentInfoPanel();
if (panel)
{
- panel->createPick(mPosGlobal, mPickPanel);
+ panel->createPick(mPosGlobal);
}
-
- LLRect rect = getRect();
- mPickPanel->reshape(rect.getWidth(), rect.getHeight());
- mPickPanel->setRect(rect);
}
else if (item == "add_to_favbar")
{
@@ -1050,17 +1031,6 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t
return false;
}
-void LLPanelPlaces::togglePickPanel(BOOL visible)
-{
- if (mPickPanel)
- {
- mPickPanel->setVisible(visible);
- mPlaceProfile->setVisible(!visible);
- updateVerbs();
- }
-
-}
-
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
if (!mPlaceProfile || !mLandmarkInfo)
@@ -1309,15 +1279,11 @@ void LLPanelPlaces::updateVerbs()
bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
- bool is_pick_panel_visible = false;
- if(mPickPanel)
- {
- is_pick_panel_visible = mPickPanel->isInVisibleChain();
- }
+
bool have_3d_pos = ! mPosGlobal.isExactlyZero();
- mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
- mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
+ mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
+ mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
mSaveBtn->setVisible(isLandmarkEditModeOn);
mCancelBtn->setVisible(isLandmarkEditModeOn);
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 3b87eb6cb9..e554099343 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -38,7 +38,6 @@ class LLLandmark;
class LLPanelLandmarkInfo;
class LLPanelPlaceProfile;
-class LLPanelPickEdit;
class LLPanelPlaceInfo;
class LLPanelPlacesTab;
class LLParcelSelection;
@@ -95,7 +94,6 @@ private:
void onOverflowButtonClicked();
void onOverflowMenuItemClicked(const LLSD& param);
bool onOverflowMenuItemEnable(const LLSD& param);
- void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
void onBackButtonClicked();
void onGearMenuClick();
void onSortingMenuClick();
@@ -103,9 +101,6 @@ private:
void onRemoveButtonClicked();
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
-
- void toggleMediaPanel();
- void togglePickPanel(BOOL visible);
void togglePlaceInfoPanel(BOOL visible);
/*virtual*/ void onVisibilityChange(BOOL new_visibility);
@@ -122,7 +117,6 @@ private:
LLPanelPlaceProfile* mPlaceProfile;
LLPanelLandmarkInfo* mLandmarkInfo;
- LLPanelPickEdit* mPickPanel;
LLToggleableMenu* mPlaceMenu;
LLToggleableMenu* mLandmarkMenu;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 5f13b223fb..f4eaa78f11 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelprofile.cpp
* @brief Profile panel implementation
*
-* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
+* Copyright (C) 2022, 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$
*/
@@ -27,32 +27,433 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelprofile.h"
-#include "llagent.h"
+// Common
+#include "llavatarnamecache.h"
+#include "llsdutil.h"
+#include "llslurl.h"
+#include "lldateutil.h" //ageFromDate
+
+// UI
+#include "llavatariconctrl.h"
+#include "llclipboard.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "lllineeditor.h"
+#include "llloadingindicator.h"
+#include "llmenubutton.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltoggleablemenu.h"
+#include "llgrouplist.h"
+#include "llurlaction.h"
+
+// Image
+#include "llimagej2c.h"
+
+// Newview
+#include "llagent.h" //gAgent
+#include "llagentpicksinfo.h"
#include "llavataractions.h"
-#include "llfloaterreg.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llcallingcard.h"
#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llpanelpicks.h"
-#include "lltabcontainer.h"
-#include "llviewercontrol.h"
-#include "llviewernetwork.h"
+#include "llfloaterprofiletexture.h"
+#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
+#include "llfilepicker.h"
+#include "llfirstuse.h"
+#include "llgroupactions.h"
+#include "lllogchat.h"
#include "llmutelist.h"
+#include "llnotificationsutil.h"
#include "llpanelblockedlist.h"
+#include "llpanelprofileclassifieds.h"
+#include "llpanelprofilepicks.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewermenu.h" //is_agent_mappable
+#include "llviewermenufile.h"
+#include "llviewertexturelist.h"
+#include "llvoiceclient.h"
#include "llweb.h"
-static const std::string PANEL_PICKS = "panel_picks";
-std::string getProfileURL(const std::string& agent_name)
+static LLPanelInjector<LLPanelProfileSecondLife> t_panel_profile_secondlife("panel_profile_secondlife");
+static LLPanelInjector<LLPanelProfileWeb> t_panel_web("panel_profile_web");
+static LLPanelInjector<LLPanelProfilePicks> t_panel_picks("panel_profile_picks");
+static LLPanelInjector<LLPanelProfileFirstLife> t_panel_firstlife("panel_profile_firstlife");
+static LLPanelInjector<LLPanelProfileNotes> t_panel_notes("panel_profile_notes");
+static LLPanelInjector<LLPanelProfile> t_panel_profile("panel_profile");
+
+static const std::string PANEL_SECONDLIFE = "panel_profile_secondlife";
+static const std::string PANEL_WEB = "panel_profile_web";
+static const std::string PANEL_PICKS = "panel_profile_picks";
+static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds";
+static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife";
+static const std::string PANEL_NOTES = "panel_profile_notes";
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile";
+static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage";
+
+
+//////////////////////////////////////////////////////////////////////////
+
+void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id)
{
- std::string url = "[WEB_PROFILE_URL][AGENT_NAME]";
- LLSD subs;
- subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
- subs["AGENT_NAME"] = agent_name;
- url = LLWeb::expandURLSubstitutions(url, subs);
- LLStringUtil::toLower(url);
- return url;
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL;
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ return;
+ }
+
+ LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id));
+ if (!floater_profile)
+ {
+ // floater is dead, so panels are dead as well
+ return;
+ }
+
+ LLPanel *panel = floater_profile->findChild<LLPanel>(PANEL_PROFILE_VIEW, TRUE);
+ LLPanelProfile *panel_profile = dynamic_cast<LLPanelProfile*>(panel);
+ if (!panel_profile)
+ {
+ LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL;
+ return;
+ }
+
+
+ // Avatar Data
+
+ LLAvatarData *avatar_data = &panel_profile->mAvatarData;
+ std::string birth_date;
+
+ avatar_data->agent_id = agent_id;
+ avatar_data->avatar_id = agent_id;
+ avatar_data->image_id = result["sl_image_id"].asUUID();
+ avatar_data->fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data->partner_id = result["partner_id"].asUUID();
+ avatar_data->about_text = result["sl_about_text"].asString();
+ avatar_data->fl_about_text = result["fl_about_text"].asString();
+ avatar_data->born_on = result["member_since"].asDate();
+ avatar_data->profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data->flags = 0;
+
+ if (result["online"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_ONLINE;
+ }
+ if (result["allow_publish"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_ALLOW_PUBLISH;
+ }
+ if (result["identified"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_IDENTIFIED;
+ }
+ if (result["transacted"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_TRANSACTED;
+ }
+
+ avatar_data->caption_index = 0;
+ if (result.has("charter_member")) // won't be present if "caption" is set
+ {
+ avatar_data->caption_index = result["charter_member"].asInteger();
+ }
+ else if (result.has("caption"))
+ {
+ avatar_data->caption_text = result["caption"].asString();
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_SECONDLIFE, TRUE);
+ LLPanelProfileSecondLife *panel_sl = dynamic_cast<LLPanelProfileSecondLife*>(panel);
+ if (panel_sl)
+ {
+ panel_sl->processProfileProperties(avatar_data);
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_WEB, TRUE);
+ LLPanelProfileWeb *panel_web = dynamic_cast<LLPanelProfileWeb*>(panel);
+ if (panel_web)
+ {
+ panel_web->setLoaded();
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_FIRSTLIFE, TRUE);
+ LLPanelProfileFirstLife *panel_first = dynamic_cast<LLPanelProfileFirstLife*>(panel);
+ if (panel_first)
+ {
+ panel_first->processProperties(avatar_data);
+ }
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_PICKS, TRUE);
+ LLPanelProfilePicks *panel_picks = dynamic_cast<LLPanelProfilePicks*>(panel);
+ if (panel_picks)
+ {
+ // Refresh pick limit before processing
+ LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks);
+ panel_picks->processProperties(&avatar_picks);
+ }
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ if (panel_sl)
+ {
+ panel_sl->processGroupProperties(&avatar_groups);
+ }
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_NOTES, TRUE);
+ LLPanelProfileNotes *panel_notes = dynamic_cast<LLPanelProfileNotes*>(panel);
+ if (panel_notes)
+ {
+ panel_notes->processProperties(&avatar_notes);
+ }
+}
+
+//TODO: changes take two minutes to propagate!
+// Add some storage that holds updated data for two minutes
+// for new instances to reuse the data
+// Profile data is only relevant to won avatar, but notes
+// are for everybody
+void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL;
+}
+
+LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+ if (!result.has("uploader"))
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
+ return LLUUID::null;
+ }
+ std::string uploader_cap = result["uploader"].asString();
+ if (uploader_cap.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ // Upload the image
+
+ LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions);
+ S64 length;
+
+ {
+ llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+ if (!instream.is_open())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ return LLUUID::null;
+ }
+ length = instream.tellg();
+ }
+
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
+ uploaderhttpOpts->setFollowRedirects(true);
+
+ result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_WARNS("AvatarProperties") << result << LL_ENDL;
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ if (result["state"].asString() != "complete")
+ {
+ if (result.has("message"))
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;
+ }
+ return LLUUID::null;
+ }
+
+ return result["new_asset"].asUUID();
}
+enum EProfileImageType
+{
+ PROFILE_IMAGE_SL,
+ PROFILE_IMAGE_FL,
+};
+
+void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle)
+{
+ LLSD data;
+ switch (type)
+ {
+ case PROFILE_IMAGE_SL:
+ data["profile-image-asset"] = "sl_image_id";
+ break;
+ case PROFILE_IMAGE_FL:
+ data["profile-image-asset"] = "fl_image_id";
+ break;
+ }
+
+ LLUUID result = post_profile_image(cap_url, data, path_to_image, handle);
+
+ // reset loading indicator
+ if (!handle->isDead())
+ {
+ switch (type)
+ {
+ case PROFILE_IMAGE_SL:
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
+ if (result.notNull())
+ {
+ panel->setProfileImageUploaded(result);
+ }
+ else
+ {
+ // failure, just stop progress indicator
+ panel->setProfileImageUploading(false);
+ }
+ break;
+ }
+ case PROFILE_IMAGE_FL:
+ {
+ LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(handle->get());
+ if (result.notNull())
+ {
+ panel->setProfileImageUploaded(result);
+ }
+ else
+ {
+ // failure, just stop progress indicator
+ panel->setProfileImageUploading(false);
+ }
+ break;
+ }
+ }
+ }
+
+ // Cleanup
+ LLFile::remove(path_to_image);
+ delete handle;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// LLProfileHandler
+
class LLProfileHandler : public LLCommandHandler
{
public:
@@ -73,6 +474,10 @@ public:
};
LLProfileHandler gProfileHandler;
+
+//////////////////////////////////////////////////////////////////////////
+// LLAgentHandler
+
class LLAgentHandler : public LLCommandHandler
{
public:
@@ -178,279 +583,2070 @@ public:
}
return true;
}
+
+ // reportAbuse is here due to convoluted avatar handling
+ // in LLScrollListCtrl and LLTextBase
+ if (verb == "reportAbuse" && web == NULL)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(avatar_id, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable");
+ }
+ return true;
+ }
return false;
}
};
LLAgentHandler gAgentHandler;
-//-- LLPanelProfile::ChildStack begins ----------------------------------------
-LLPanelProfile::ChildStack::ChildStack()
-: mParent(NULL)
+///----------------------------------------------------------------------------
+/// LLFloaterProfilePermissions
+///----------------------------------------------------------------------------
+
+class LLFloaterProfilePermissions
+ : public LLFloater
+ , public LLFriendObserver
{
+public:
+ LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id);
+ ~LLFloaterProfilePermissions();
+ BOOL postBuild() override;
+ void onOpen(const LLSD& key) override;
+ void draw() override;
+ void changed(U32 mask) override; // LLFriendObserver
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+ bool hasUnsavedChanges() { return mHasUnsavedPermChanges; }
+
+ void onApplyRights();
+
+private:
+ void fillRightsData();
+ void rightsConfirmationCallback(const LLSD& notification, const LLSD& response);
+ void confirmModifyRights(bool grant);
+ void onCommitSeeOnlineRights();
+ void onCommitEditRights();
+ void onCancel();
+
+ LLTextBase* mDescription;
+ LLCheckBoxCtrl* mOnlineStatus;
+ LLCheckBoxCtrl* mMapRights;
+ LLCheckBoxCtrl* mEditObjectRights;
+ LLButton* mOkBtn;
+ LLButton* mCancelBtn;
+
+ LLUUID mAvatarID;
+ F32 mContextConeOpacity;
+ bool mHasUnsavedPermChanges;
+ LLHandle<LLView> mOwnerHandle;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+LLFloaterProfilePermissions::LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id)
+ : LLFloater(LLSD())
+ , mAvatarID(avatar_id)
+ , mContextConeOpacity(0.0f)
+ , mHasUnsavedPermChanges(false)
+ , mOwnerHandle(owner->getHandle())
+{
+ buildFromFile("floater_profile_permissions.xml");
}
-LLPanelProfile::ChildStack::~ChildStack()
+LLFloaterProfilePermissions::~LLFloaterProfilePermissions()
{
- while (mStack.size() != 0)
- {
- view_list_t& top = mStack.back();
- for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
- {
- LLView* viewp = *it;
- if (viewp)
- {
- viewp->die();
- }
- }
- mStack.pop_back();
- }
+ mAvatarNameCacheConnection.disconnect();
+ if (mAvatarID.notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
+ }
}
-void LLPanelProfile::ChildStack::setParent(LLPanel* parent)
+BOOL LLFloaterProfilePermissions::postBuild()
{
- llassert_always(parent != NULL);
- mParent = parent;
+ mDescription = getChild<LLTextBase>("perm_description");
+ mOnlineStatus = getChild<LLCheckBoxCtrl>("online_check");
+ mMapRights = getChild<LLCheckBoxCtrl>("map_check");
+ mEditObjectRights = getChild<LLCheckBoxCtrl>("objects_check");
+ mOkBtn = getChild<LLButton>("perms_btn_ok");
+ mCancelBtn = getChild<LLButton>("perms_btn_cancel");
+
+ mOnlineStatus->setCommitCallback([this](LLUICtrl*, void*) { onCommitSeeOnlineRights(); }, nullptr);
+ mMapRights->setCommitCallback([this](LLUICtrl*, void*) { mHasUnsavedPermChanges = true; }, nullptr);
+ mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitEditRights(); }, nullptr);
+ mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr);
+ mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr);
+
+ return TRUE;
}
-/// Save current parent's child views and remove them from the child list.
-bool LLPanelProfile::ChildStack::push()
+void LLFloaterProfilePermissions::onOpen(const LLSD& key)
{
- view_list_t vlist = *mParent->getChildList();
+ if (LLAvatarActions::isFriend(mAvatarID))
+ {
+ LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);
+ fillRightsData();
+ }
- for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it)
- {
- LLView* viewp = *it;
- mParent->removeChild(viewp);
- }
+ mCancelBtn->setFocus(true);
- mStack.push_back(vlist);
- dump();
- return true;
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterProfilePermissions::onAvatarNameCache, this, _1, _2));
}
-/// Restore saved children (adding them back to the child list).
-bool LLPanelProfile::ChildStack::pop()
+void LLFloaterProfilePermissions::draw()
{
- if (mStack.size() == 0)
- {
- LL_WARNS() << "Empty stack" << LL_ENDL;
- llassert(mStack.size() == 0);
- return false;
- }
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+ LLFloater::draw();
+}
- view_list_t& top = mStack.back();
- for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
- {
- LLView* viewp = *it;
- mParent->addChild(viewp);
- }
+void LLFloaterProfilePermissions::changed(U32 mask)
+{
+ if (mask != LLFriendObserver::ONLINE)
+ {
+ fillRightsData();
+ }
+}
- mStack.pop_back();
- dump();
- return true;
+void LLFloaterProfilePermissions::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ LLStringUtil::format_map_t args;
+ args["[AGENT_NAME]"] = av_name.getDisplayName();
+ std::string descritpion = getString("description_string", args);
+ mDescription->setValue(descritpion);
}
-/// Temporarily add all saved children back.
-void LLPanelProfile::ChildStack::preParentReshape()
+void LLFloaterProfilePermissions::fillRightsData()
{
- mSavedStack = mStack;
- while(mStack.size() > 0)
- {
- pop();
- }
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+
+ BOOL see_online = LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE;
+ mOnlineStatus->setValue(see_online);
+ mMapRights->setEnabled(see_online);
+ mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE);
+ }
+ else
+ {
+ closeFloater();
+ LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL;
+ }
}
-/// Add the temporarily saved children back.
-void LLPanelProfile::ChildStack::postParentReshape()
+void LLFloaterProfilePermissions::rightsConfirmationCallback(const LLSD& notification,
+ const LLSD& response)
{
- mStack = mSavedStack;
- mSavedStack = stack_t();
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) // canceled
+ {
+ mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE);
+ }
+ else
+ {
+ mHasUnsavedPermChanges = true;
+ }
+}
- for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it)
- {
- const view_list_t& vlist = (*stack_it);
- for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
- {
- LLView* viewp = *list_it;
- LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL;
- mParent->removeChild(viewp);
- }
- }
+void LLFloaterProfilePermissions::confirmModifyRights(bool grant)
+{
+ LLSD args;
+ args["NAME"] = LLSLURL("agent", mAvatarID, "completename").getSLURLString();
+ LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(),
+ boost::bind(&LLFloaterProfilePermissions::rightsConfirmationCallback, this, _1, _2));
}
-void LLPanelProfile::ChildStack::dump()
+void LLFloaterProfilePermissions::onCommitSeeOnlineRights()
{
- unsigned lvl = 0;
- LL_DEBUGS() << "child stack dump:" << LL_ENDL;
- for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl)
- {
- std::ostringstream dbg_line;
- dbg_line << "lvl #" << lvl << ":";
- const view_list_t& vlist = (*stack_it);
- for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
- {
- dbg_line << " " << (*list_it)->getName();
- }
- LL_DEBUGS() << dbg_line.str() << LL_ENDL;
- }
+ bool see_online = mOnlineStatus->getValue().asBoolean();
+ mMapRights->setEnabled(see_online);
+ if (see_online)
+ {
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+ mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ }
+ else
+ {
+ closeFloater();
+ LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mMapRights->setValue(FALSE);
+ }
+ mHasUnsavedPermChanges = true;
}
-//-- LLPanelProfile::ChildStack ends ------------------------------------------
+void LLFloaterProfilePermissions::onCommitEditRights()
+{
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
-LLPanelProfile::LLPanelProfile()
- : LLPanel()
- , mAvatarId(LLUUID::null)
+ if (!buddy_relationship)
+ {
+ LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Closing floater." << LL_ENDL;
+ closeFloater();
+ return;
+ }
+
+ bool allow_modify_objects = mEditObjectRights->getValue().asBoolean();
+
+ // if modify objects checkbox clicked
+ if (buddy_relationship->isRightGrantedTo(
+ LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects)
+ {
+ confirmModifyRights(allow_modify_objects);
+ }
+}
+
+void LLFloaterProfilePermissions::onApplyRights()
+{
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+
+ if (!buddy_relationship)
+ {
+ LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL;
+ return;
+ }
+
+ S32 rights = 0;
+
+ if (mOnlineStatus->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_ONLINE_STATUS;
+ }
+ if (mMapRights->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_MAP_LOCATION;
+ }
+ if (mEditObjectRights->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_MODIFY_OBJECTS;
+ }
+
+ LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(mAvatarID, rights);
+
+ closeFloater();
+}
+
+void LLFloaterProfilePermissions::onCancel()
{
- mChildStack.setParent(this);
+ closeFloater();
}
-BOOL LLPanelProfile::postBuild()
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileSecondLife
+
+LLPanelProfileSecondLife::LLPanelProfileSecondLife()
+ : LLPanelProfileTab()
+ , mAvatarNameCacheConnection()
+ , mHasUnsavedDescriptionChanges(false)
+ , mWaitingForImageUpload(false)
+ , mAllowPublish(false)
+{
+}
+
+LLPanelProfileSecondLife::~LLPanelProfileSecondLife()
+{
+ if (getAvatarId().notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ }
+
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
+ }
+
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
+
+BOOL LLPanelProfileSecondLife::postBuild()
+{
+ mGroupList = getChild<LLGroupList>("group_list");
+ mShowInSearchCombo = getChild<LLComboBox>("show_in_search");
+ mSecondLifePic = getChild<LLIconCtrl>("2nd_life_pic");
+ mSecondLifePicLayout = getChild<LLPanel>("image_panel");
+ mDescriptionEdit = getChild<LLTextEditor>("sl_description_edit");
+ mAgentActionMenuButton = getChild<LLMenuButton>("agent_actions_menu");
+ mSaveDescriptionChanges = getChild<LLButton>("save_description_changes");
+ mDiscardDescriptionChanges = getChild<LLButton>("discard_description_changes");
+ mCanSeeOnlineIcon = getChild<LLIconCtrl>("can_see_online");
+ mCantSeeOnlineIcon = getChild<LLIconCtrl>("cant_see_online");
+ mCanSeeOnMapIcon = getChild<LLIconCtrl>("can_see_on_map");
+ mCantSeeOnMapIcon = getChild<LLIconCtrl>("cant_see_on_map");
+ mCanEditObjectsIcon = getChild<LLIconCtrl>("can_edit_objects");
+ mCantEditObjectsIcon = getChild<LLIconCtrl>("cant_edit_objects");
+
+ mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr);
+ mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); });
+ mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); });
+ mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
+ mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
+ mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
+
+ mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileSecondLife::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+
+ LLUUID avatar_id = getAvatarId();
+
+ BOOL own_profile = getSelfProfile();
+
+ mGroupList->setShowNone(!own_profile);
+
+ childSetVisible("notes_panel", !own_profile);
+ childSetVisible("settings_panel", own_profile);
+ childSetVisible("about_buttons_panel", own_profile);
+
+ if (own_profile)
+ {
+ // Group list control cannot toggle ForAgent loading
+ // Less than ideal, but viewing own profile via search is edge case
+ mGroupList->enableForAgent(false);
+ }
+
+ // Init menu, menu needs to be created in scope of a registar to work correctly.
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit;
+ commit.add("Profile.Commit", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); });
+
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable;
+ enable.add("Profile.EnableItem", [this](LLUICtrl*, const LLSD& userdata) { return onEnableMenu(userdata); });
+ enable.add("Profile.CheckItem", [this](LLUICtrl*, const LLSD& userdata) { return onCheckMenu(userdata); });
+
+ if (own_profile)
+ {
+ mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT);
+ }
+ else
+ {
+ // Todo: use PeopleContextMenu instead?
+ mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT);
+ }
+
+ mDescriptionEdit->setParseHTML(!own_profile);
+
+ if (!own_profile)
+ {
+ mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE);
+ updateOnlineStatus();
+ fillRightsData();
+ }
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
+}
+
+void LLPanelProfileSecondLife::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ else
+ {
+ LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+ }
+}
+
+void LLPanelProfileSecondLife::refreshName()
+{
+ if (!mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
+ }
+}
+
+void LLPanelProfileSecondLife::resetData()
+{
+ resetLoading();
+
+ // Set default image and 1:1 dimensions for it
+ mSecondLifePic->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+
+ LLRect imageRect = mSecondLifePicLayout->getRect();
+ mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight());
+
+ setDescriptionText(LLStringUtil::null);
+ mGroups.clear();
+ mGroupList->setGroups(mGroups);
+
+ bool own_profile = getSelfProfile();
+ mCanSeeOnlineIcon->setVisible(false);
+ mCantSeeOnlineIcon->setVisible(!own_profile);
+ mCanSeeOnMapIcon->setVisible(false);
+ mCantSeeOnMapIcon->setVisible(!own_profile);
+ mCanEditObjectsIcon->setVisible(false);
+ mCantEditObjectsIcon->setVisible(!own_profile);
+
+ mCanSeeOnlineIcon->setEnabled(false);
+ mCantSeeOnlineIcon->setEnabled(false);
+ mCanSeeOnMapIcon->setEnabled(false);
+ mCantSeeOnMapIcon->setEnabled(false);
+ mCanEditObjectsIcon->setEnabled(false);
+ mCantEditObjectsIcon->setEnabled(false);
+
+ childSetVisible("partner_layout", FALSE);
+}
+
+void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data)
+{
+ LLUUID avatar_id = getAvatarId();
+ const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile())
+ {
+ // Relies onto friend observer to get information about online status updates.
+ // Once SL-17506 gets implemented, condition might need to become:
+ // (gAgent.isGodlike() || isRightGrantedFrom || flags & AVATAR_ONLINE)
+ processOnlineStatus(relationship != NULL,
+ gAgent.isGodlike() || relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS),
+ (avatar_data->flags & AVATAR_ONLINE));
+ }
+
+ fillCommonData(avatar_data);
+
+ fillPartnerData(avatar_data);
+
+ fillAccountStatus(avatar_data);
+
+ setLoaded();
+}
+
+void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups)
+{
+
+ LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
+ const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end();
+
+ for (; it_end != it; ++it)
+ {
+ LLAvatarGroups::LLGroupData group_data = *it;
+ mGroups[group_data.group_name] = group_data.group_id;
+ }
+
+ mGroupList->setGroups(mGroups);
+}
+
+void LLPanelProfileSecondLife::openGroupProfile()
+{
+ LLUUID group_id = mGroupList->getSelectedUUID();
+ LLGroupActions::show(group_id);
+}
+
+void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+ getChild<LLUICtrl>("display_name")->setValue(av_name.getDisplayName());
+ getChild<LLUICtrl>("user_name")->setValue(av_name.getAccountName());
+}
+
+void LLPanelProfileSecondLife::setProfileImageUploading(bool loading)
+{
+ LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator");
+ indicator->setVisible(loading);
+ if (loading)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ mWaitingForImageUpload = loading;
+}
+
+void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id)
+{
+ mSecondLifePic->setValue(image_asset_id);
+ mImageId = image_asset_id;
+
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
+ if (imagep->getFullHeight())
+ {
+ onImageLoaded(true, imagep);
+ }
+ else
+ {
+ imagep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL,
+ FALSE,
+ FALSE,
+ new LLHandle<LLPanel>(getHandle()),
+ NULL,
+ FALSE);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ }
+
+ setProfileImageUploading(false);
+}
+
+bool LLPanelProfileSecondLife::hasUnsavedChanges()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (floater)
+ {
+ LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater);
+ if (perm && perm->hasUnsavedChanges())
+ {
+ return true;
+ }
+ }
+ // if floater
+ return mHasUnsavedDescriptionChanges;
+}
+
+void LLPanelProfileSecondLife::commitUnsavedChanges()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (floater)
+ {
+ LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater);
+ if (perm && perm->hasUnsavedChanges())
+ {
+ perm->onApplyRights();
+ }
+ }
+ if (mHasUnsavedDescriptionChanges)
+ {
+ onSaveDescriptionChanges();
+ }
+}
+
+void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data)
+{
+ // Refresh avatar id in cache with new info to prevent re-requests
+ // and to make sure icons in text will be up to date
+ LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id);
+
+ fillAgeData(avatar_data->born_on);
+
+ setDescriptionText(avatar_data->about_text);
+
+ if (avatar_data->image_id.notNull())
+ {
+ mSecondLifePic->setValue(avatar_data->image_id);
+ mImageId = avatar_data->image_id;
+ }
+ else
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+ }
+
+ // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id);
+ if (imagep->getFullHeight())
+ {
+ onImageLoaded(true, imagep);
+ }
+ else
+ {
+ imagep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL,
+ FALSE,
+ FALSE,
+ new LLHandle<LLPanel>(getHandle()),
+ NULL,
+ FALSE);
+ }
+
+ if (getSelfProfile())
+ {
+ mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH;
+ mShowInSearchCombo->setValue((BOOL)mAllowPublish);
+ }
+}
+
+void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data)
+{
+ LLTextBox* partner_text_ctrl = getChild<LLTextBox>("partner_link");
+ if (avatar_data->partner_id.notNull())
+ {
+ childSetVisible("partner_layout", TRUE);
+ LLStringUtil::format_map_t args;
+ args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString();
+ std::string partner_text = getString("partner_text", args);
+ partner_text_ctrl->setText(partner_text);
+ }
+ else
+ {
+ childSetVisible("partner_layout", FALSE);
+ }
+}
+
+void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data)
+{
+ LLStringUtil::format_map_t args;
+ args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data);
+ args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data);
+
+ std::string caption_text = getString("CaptionTextAcctInfo", args);
+ getChild<LLUICtrl>("account_info")->setValue(caption_text);
+}
+
+void LLPanelProfileSecondLife::fillRightsData()
+{
+ if (getSelfProfile())
+ {
+ return;
+ }
+
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+ bool can_see_online = LLRelationship::GRANT_ONLINE_STATUS & rights;
+ bool can_see_on_map = LLRelationship::GRANT_MAP_LOCATION & rights;
+ bool can_edit_objects = LLRelationship::GRANT_MODIFY_OBJECTS & rights;
+
+ mCanSeeOnlineIcon->setVisible(can_see_online);
+ mCantSeeOnlineIcon->setVisible(!can_see_online);
+ mCanSeeOnMapIcon->setVisible(can_see_on_map);
+ mCantSeeOnMapIcon->setVisible(!can_see_on_map);
+ mCanEditObjectsIcon->setVisible(can_edit_objects);
+ mCantEditObjectsIcon->setVisible(!can_edit_objects);
+
+ mCanSeeOnlineIcon->setEnabled(true);
+ mCantSeeOnlineIcon->setEnabled(true);
+ mCanSeeOnMapIcon->setEnabled(true);
+ mCantSeeOnMapIcon->setEnabled(true);
+ mCanEditObjectsIcon->setEnabled(true);
+ mCantEditObjectsIcon->setEnabled(true);
+ }
+ else
+ {
+ mCanSeeOnlineIcon->setVisible(false);
+ mCantSeeOnlineIcon->setVisible(false);
+ mCanSeeOnMapIcon->setVisible(false);
+ mCantSeeOnMapIcon->setVisible(false);
+ mCanEditObjectsIcon->setVisible(false);
+ mCantEditObjectsIcon->setVisible(false);
+ }
+}
+
+void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on)
+{
+ std::string name_and_date = getString("date_format");
+ LLSD args_name;
+ args_name["datetime"] = (S32)born_on.secondsSinceEpoch();
+ LLStringUtil::format(name_and_date, args_name);
+ getChild<LLUICtrl>("sl_birth_date")->setValue(name_and_date);
+
+ std::string register_date = getString("age_format");
+ LLSD args_age;
+ args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now());
+ LLStringUtil::format(register_date, args_age);
+ getChild<LLUICtrl>("user_age")->setValue(register_date);
+}
+
+void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep)
+{
+ LLRect imageRect = mSecondLifePicLayout->getRect();
+ if (!success || imagep->getFullWidth() == imagep->getFullHeight())
+ {
+ mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth());
+ }
+ else
+ {
+ // assume 3:4, for sake of firestorm
+ mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth() * 3 / 4);
+ }
+}
+
+//static
+void LLPanelProfileSecondLife::onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ if (!userdata) return;
+
+ LLHandle<LLPanel>* handle = (LLHandle<LLPanel>*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
+ if (panel)
+ {
+ panel->onImageLoaded(success, src_vi);
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
+
+// virtual, called by LLAvatarTracker
+void LLPanelProfileSecondLife::changed(U32 mask)
+{
+ updateOnlineStatus();
+ if (mask != LLFriendObserver::ONLINE)
+ {
+ fillRightsData();
+ }
+}
+
+// virtual, called by LLVoiceClient
+void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(getAvatarId()) ? LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) : TRUE);
+}
+
+void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ }
+
+ LLPanelProfileTab::setAvatarId(avatar_id);
+
+ if (LLAvatarActions::isFriend(getAvatarId()))
+ {
+ LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this);
+ }
+ }
+}
+
+// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880
+void LLPanelProfileSecondLife::updateOnlineStatus()
+{
+ const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if (relationship != NULL)
+ {
+ // For friend let check if he allowed me to see his status
+ bool online = relationship->isOnline();
+ bool perm_granted = relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
+ processOnlineStatus(true, perm_granted, online);
+ }
+ else
+ {
+ childSetVisible("frind_layout", false);
+ childSetVisible("online_layout", false);
+ childSetVisible("offline_layout", false);
+ }
+}
+
+void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online)
+{
+ childSetVisible("frind_layout", is_friend);
+ childSetVisible("online_layout", online && show_online);
+ childSetVisible("offline_layout", !online && show_online);
+}
+
+void LLPanelProfileSecondLife::setLoaded()
+{
+ LLPanelProfileTab::setLoaded();
+
+ if (getSelfProfile())
+ {
+ mShowInSearchCombo->setEnabled(TRUE);
+ mDescriptionEdit->setEnabled(TRUE);
+ }
+}
+
+
+
+class LLProfileImagePicker : public LLFilePickerThread
+{
+public:
+ LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle);
+ ~LLProfileImagePicker();
+ void notify(const std::vector<std::string>& filenames) override;
+
+private:
+ LLHandle<LLPanel> *mHandle;
+ EProfileImageType mType;
+};
+
+LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle)
+ : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE),
+ mHandle(handle),
+ mType(type)
+{
+}
+
+LLProfileImagePicker::~LLProfileImagePicker()
+{
+ delete mHandle;
+}
+
+void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)
+{
+ if (mHandle->isDead())
+ {
+ return;
+ }
+ if (filenames.empty())
+ {
+ return;
+ }
+ std::string file_path = filenames[0];
+ if (file_path.empty())
+ {
+ return;
+ }
+
+ // generate a temp texture file for coroutine
+ std::string temp_file = gDirUtilp->getTempFilename();
+ U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path));
+ const S32 MAX_DIM = 256;
+ if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))
+ {
+ //todo: image not supported notification
+ LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL;
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+ if (cap_url.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL;
+ return;
+ }
+
+ switch (mType)
+ {
+ case PROFILE_IMAGE_SL:
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get());
+ panel->setProfileImageUploading(true);
+ }
+ break;
+ case PROFILE_IMAGE_FL:
+ {
+ LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(mHandle->get());
+ panel->setProfileImageUploading(true);
+ }
+ break;
+ }
+
+ LLCoros::instance().launch("postAgentUserImageCoro",
+ boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle));
+
+ mHandle = nullptr; // transferred to post_profile_image_coro
+}
+
+void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ // todo: consider moving this into LLAvatarActions::onCommit(name, id)
+ // and making all other flaoters, like people menu do the same
+ if (item_name == "im")
+ {
+ LLAvatarActions::startIM(agent_id);
+ }
+ else if (item_name == "offer_teleport")
+ {
+ LLAvatarActions::offerTeleport(agent_id);
+ }
+ else if (item_name == "request_teleport")
+ {
+ LLAvatarActions::teleportRequest(agent_id);
+ }
+ else if (item_name == "voice_call")
+ {
+ LLAvatarActions::startCall(agent_id);
+ }
+ else if (item_name == "chat_history")
+ {
+ LLAvatarActions::viewChatHistory(agent_id);
+ }
+ else if (item_name == "add_friend")
+ {
+ LLAvatarActions::requestFriendshipDialog(agent_id);
+ }
+ else if (item_name == "remove_friend")
+ {
+ LLAvatarActions::removeFriendDialog(agent_id);
+ }
+ else if (item_name == "invite_to_group")
+ {
+ LLAvatarActions::inviteToGroup(agent_id);
+ }
+ else if (item_name == "can_show_on_map")
+ {
+ LLAvatarActions::showOnMap(agent_id);
+ }
+ else if (item_name == "share")
+ {
+ LLAvatarActions::share(agent_id);
+ }
+ else if (item_name == "pay")
+ {
+ LLAvatarActions::pay(agent_id);
+ }
+ else if (item_name == "toggle_block_agent")
+ {
+ LLAvatarActions::toggleBlock(agent_id);
+ }
+ else if (item_name == "copy_user_id")
+ {
+ LLWString wstr = utf8str_to_wstring(getAvatarId().asString());
+ LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size());
+ }
+ else if (item_name == "agent_permissions")
+ {
+ onShowAgentPermissionsDialog();
+ }
+ else if (item_name == "copy_display_name"
+ || item_name == "copy_username")
+ {
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(getAvatarId(), &av_name))
+ {
+ // shouldn't happen, option is supposed to be invisible while name is fetching
+ LL_WARNS() << "Failed to get agent data" << LL_ENDL;
+ return;
+ }
+ LLWString wstr;
+ if (item_name == "copy_display_name")
+ {
+ wstr = utf8str_to_wstring(av_name.getDisplayName(true));
+ }
+ else if (item_name == "copy_username")
+ {
+ wstr = utf8str_to_wstring(av_name.getUserName());
+ }
+ LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size());
+ }
+ else if (item_name == "edit_display_name")
+ {
+ LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2));
+ LLFirstUse::setDisplayName(false);
+ }
+ else if (item_name == "edit_partner")
+ {
+ std::string url = "https://[GRID]/my/account/partners.php";
+ LLSD subs;
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLUrlAction::openURL(url);
+ }
+ else if (item_name == "upload_photo")
+ {
+ (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(getHandle())))->getFile();
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+ }
+ else if (item_name == "change_photo")
+ {
+ onShowTexturePicker();
+ }
+ else if (item_name == "remove_photo")
+ {
+ onCommitProfileImage(LLUUID::null);
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+ }
+}
+
+bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ if (item_name == "offer_teleport" || item_name == "request_teleport")
+ {
+ return LLAvatarActions::canOfferTeleport(agent_id);
+ }
+ else if (item_name == "voice_call")
+ {
+ return mVoiceStatus;
+ }
+ else if (item_name == "chat_history")
+ {
+ return LLLogChat::isTranscriptExist(agent_id);
+ }
+ else if (item_name == "add_friend")
+ {
+ return !LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "remove_friend")
+ {
+ return LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "can_show_on_map")
+ {
+ return (LLAvatarTracker::instance().isBuddyOnline(agent_id) && is_agent_mappable(agent_id))
+ || gAgent.isGodlike();
+ }
+ else if (item_name == "toggle_block_agent")
+ {
+ return LLAvatarActions::canBlock(agent_id);
+ }
+ else if (item_name == "agent_permissions")
+ {
+ return LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "copy_display_name"
+ || item_name == "copy_username")
+ {
+ return !mAvatarNameCacheConnection.connected();
+ }
+ else if (item_name == "upload_photo"
+ || item_name == "change_photo")
+ {
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+ return !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded();
+ }
+ else if (item_name == "remove_photo")
+ {
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded();
+ }
+
+ return false;
+}
+
+bool LLPanelProfileSecondLife::onCheckMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ if (item_name == "toggle_block_agent")
+ {
+ return LLAvatarActions::isBlocked(agent_id);
+ }
+ return false;
+}
+
+void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name)
{
- LLPanelPicks* panel_picks = findChild<LLPanelPicks>(PANEL_PICKS);
- panel_picks->setProfilePanel(this);
+ if (av_name.getDisplayName().empty())
+ {
+ // something is wrong, tell user to try again later
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ return;
+ }
- getTabContainer()[PANEL_PICKS] = panel_picks;
+ LL_INFOS("LegacyProfile") << "name-change now " << LLDate::now() << " next_update "
+ << LLDate(av_name.mNextUpdate) << LL_ENDL;
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
- return TRUE;
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // if the update time is more than a year in the future, it means updates have been blocked
+ // show a more general message
+ static const S32 YEAR = 60*60*24*365;
+ if (now_secs + YEAR < av_name.mNextUpdate)
+ {
+ LLNotificationsUtil::add("SetDisplayNameBlocked");
+ return;
+ }
+ }
+
+ LLFloaterReg::showInstance("display_name");
+}
+
+void LLPanelProfileSecondLife::setDescriptionText(const std::string &text)
+{
+ mSaveDescriptionChanges->setEnabled(FALSE);
+ mDiscardDescriptionChanges->setEnabled(FALSE);
+ mHasUnsavedDescriptionChanges = false;
+
+ mDescriptionText = text;
+ mDescriptionEdit->setValue(mDescriptionText);
}
-// virtual
-void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent)
+void LLPanelProfileSecondLife::onSetDescriptionDirty()
{
- // Temporarily add saved children back and reshape them.
- mChildStack.preParentReshape();
- LLPanel::reshape(width, height, called_from_parent);
- mChildStack.postParentReshape();
+ mSaveDescriptionChanges->setEnabled(TRUE);
+ mDiscardDescriptionChanges->setEnabled(TRUE);
+ mHasUnsavedDescriptionChanges = true;
+}
+
+void LLPanelProfileSecondLife::onShowInSearchCallback()
+{
+ S32 value = mShowInSearchCombo->getValue().asInteger();
+ if (mAllowPublish == (bool)value)
+ {
+ return;
+ }
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ mAllowPublish = value;
+ LLSD data;
+ data["allow_publish"] = mAllowPublish;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileSecondLife::onSaveDescriptionChanges()
+{
+ mDescriptionText = mDescriptionEdit->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveDescriptionChanges->setEnabled(FALSE);
+ mDiscardDescriptionChanges->setEnabled(FALSE);
+ mHasUnsavedDescriptionChanges = false;
+}
+
+void LLPanelProfileSecondLife::onDiscardDescriptionChanges()
+{
+ setDescriptionText(mDescriptionText);
+}
+
+void LLPanelProfileSecondLife::onShowAgentPermissionsDialog()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (!floater)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(parent_floater, getAvatarId());
+ mFloaterPermissionsHandle = perms->getHandle();
+ perms->openFloater();
+ perms->setVisibleAndFrontmost(TRUE);
+
+ parent_floater->addDependentFloater(mFloaterPermissionsHandle);
+ }
+ }
+ else // already open
+ {
+ floater->setMinimized(FALSE);
+ floater->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileSecondLife::onShowAgentProfileTexture()
+{
+ if (!getIsLoaded())
+ {
+ return;
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (!floater)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater);
+ mFloaterProfileTextureHandle = texture_view->getHandle();
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ texture_view->openFloater();
+ texture_view->setVisibleAndFrontmost(TRUE);
+
+ parent_floater->addDependentFloater(mFloaterProfileTextureHandle);
+ }
+ }
+ else // already open
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ texture_view->setMinimized(FALSE);
+ texture_view->setVisibleAndFrontmost(TRUE);
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ }
+}
+
+void LLPanelProfileSecondLife::onShowTexturePicker()
+{
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ // because inventory construction is somewhat slow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker(
+ this,
+ mImageId,
+ LLUUID::null,
+ mImageId,
+ FALSE,
+ FALSE,
+ "SELECT PHOTO",
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ FALSE,
+ NULL);
+
+ mFloaterTexturePickerHandle = texture_floaterp->getHandle();
+
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
+ {
+ if (op == LLTextureCtrl::TEXTURE_SELECT)
+ {
+ LLUUID image_asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ if (id.notNull())
+ {
+ image_asset_id = id;
+ }
+ else
+ {
+ image_asset_id = floaterp->getAssetID();
+ }
+ }
+
+ onCommitProfileImage(image_asset_id);
+ }
+ });
+ texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
+ texture_floaterp->setCanApply(false, true);
+
+ parent_floater->addDependentFloater(mFloaterTexturePickerHandle);
+
+ texture_floaterp->openFloater();
+ texture_floaterp->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ floaterp->setMinimized(FALSE);
+ floaterp->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id)
+{
+ if (mImageId == id)
+ {
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLSD params;
+ params["sl_image_id"] = id;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params));
+
+ mImageId = id;
+ if (mImageId == LLUUID::null)
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ }
+ else
+ {
+ mSecondLifePic->setValue(mImageId);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (mImageId == LLUUID::null)
+ {
+ texture_view->resetAsset();
+ }
+ else
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileWeb
+
+LLPanelProfileWeb::LLPanelProfileWeb()
+ : LLPanelProfileTab()
+ , mWebBrowser(NULL)
+ , mAvatarNameCacheConnection()
+{
+}
+
+LLPanelProfileWeb::~LLPanelProfileWeb()
+{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
+
+void LLPanelProfileWeb::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileWeb::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLPanelProfileWeb::postBuild()
+{
+ mWebBrowser = getChild<LLMediaCtrl>("profile_html");
+ mWebBrowser->addObserver(this);
+ mWebBrowser->setHomePageUrl("about:blank");
+
+ return TRUE;
+}
+
+void LLPanelProfileWeb::resetData()
+{
+ mWebBrowser->navigateHome();
+}
+
+void LLPanelProfileWeb::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull() && !mURLWebProfile.empty())
+ {
+ setIsLoading();
+
+ mWebBrowser->setVisible(TRUE);
+ mPerformanceTimer.start();
+ mWebBrowser->navigateTo(mURLWebProfile, HTTP_CONTENT_TEXT_HTML);
+ }
+}
+
+void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ std::string username = av_name.getAccountName();
+ if (username.empty())
+ {
+ username = LLCacheName::buildUsername(av_name.getDisplayName());
+ }
+ else
+ {
+ LLStringUtil::replaceChar(username, ' ', '.');
+ }
+
+ mURLWebProfile = getProfileURL(username, true);
+ if (mURLWebProfile.empty())
+ {
+ return;
+ }
+
+ //if the tab was opened before name was resolved, load the panel now
+ updateData();
+}
+
+void LLPanelProfileWeb::onCommitLoad(LLUICtrl* ctrl)
+{
+ if (!mURLHome.empty())
+ {
+ LLSD::String valstr = ctrl->getValue().asString();
+ if (valstr.empty())
+ {
+ mWebBrowser->setVisible(TRUE);
+ mPerformanceTimer.start();
+ mWebBrowser->navigateTo( mURLHome, HTTP_CONTENT_TEXT_HTML );
+ }
+ else if (valstr == "popout")
+ {
+ // open in viewer's browser, new window
+ LLWeb::loadURLInternal(mURLHome);
+ }
+ else if (valstr == "external")
+ {
+ // open in external browser
+ LLWeb::loadURLExternal(mURLHome);
+ }
+ }
+}
+
+void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ switch(event)
+ {
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ childSetValue("status_text", LLSD( self->getStatusText() ) );
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ if (mFirstNavigate)
+ {
+ mFirstNavigate = false;
+ }
+ else
+ {
+ mPerformanceTimer.start();
+ }
+ }
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LLStringUtil::format_map_t args;
+ args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32());
+ childSetValue("status_text", LLSD( getString("LoadTime", args)) );
+ }
+ break;
+
+ default:
+ // Having a default case makes the compiler happy.
+ break;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelProfileFirstLife::LLPanelProfileFirstLife()
+ : LLPanelProfileTab()
+ , mHasUnsavedChanges(false)
+{
+}
+
+LLPanelProfileFirstLife::~LLPanelProfileFirstLife()
+{
+}
+
+BOOL LLPanelProfileFirstLife::postBuild()
+{
+ mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit");
+ mPicture = getChild<LLIconCtrl>("real_world_pic");
+
+ mUploadPhoto = getChild<LLButton>("fl_upload_image");
+ mChangePhoto = getChild<LLButton>("fl_change_image");
+ mRemovePhoto = getChild<LLButton>("fl_remove_image");
+ mSaveChanges = getChild<LLButton>("fl_save_changes");
+ mDiscardChanges = getChild<LLButton>("fl_discard_changes");
+
+ mUploadPhoto->setCommitCallback([this](LLUICtrl*, void*) { onUploadPhoto(); }, nullptr);
+ mChangePhoto->setCommitCallback([this](LLUICtrl*, void*) { onChangePhoto(); }, nullptr);
+ mRemovePhoto->setCommitCallback([this](LLUICtrl*, void*) { onRemovePhoto(); }, nullptr);
+ mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
+ mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
+ mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileFirstLife::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ if (!getSelfProfile())
+ {
+ // Otherwise as the only focusable element it will be selected
+ mDescriptionEdit->setTabStop(FALSE);
+ }
+
+ resetData();
+}
+
+void LLPanelProfileFirstLife::setProfileImageUploading(bool loading)
+{
+ mUploadPhoto->setEnabled(!loading);
+ mChangePhoto->setEnabled(!loading);
+ mRemovePhoto->setEnabled(!loading && mImageId.notNull());
+
+ LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator");
+ indicator->setVisible(loading);
+ if (loading)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+}
+
+void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id)
+{
+ mPicture->setValue(image_asset_id);
+ mImageId = image_asset_id;
+ setProfileImageUploading(false);
+}
+
+void LLPanelProfileFirstLife::commitUnsavedChanges()
+{
+ if (mHasUnsavedChanges)
+ {
+ onSaveDescriptionChanges();
+ }
+}
+
+void LLPanelProfileFirstLife::onUploadPhoto()
+{
+ (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(getHandle())))->getFile();
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+}
+
+void LLPanelProfileFirstLife::onChangePhoto()
+{
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ // because inventory construction is somewhat slow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker(
+ this,
+ mImageId,
+ LLUUID::null,
+ mImageId,
+ FALSE,
+ FALSE,
+ "SELECT PHOTO",
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ FALSE,
+ NULL);
+
+ mFloaterTexturePickerHandle = texture_floaterp->getHandle();
+
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
+ {
+ if (op == LLTextureCtrl::TEXTURE_SELECT)
+ {
+ LLUUID image_asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ if (id.notNull())
+ {
+ image_asset_id = id;
+ }
+ else
+ {
+ image_asset_id = floaterp->getAssetID();
+ }
+ }
+
+ onCommitPhoto(image_asset_id);
+ }
+ });
+ texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setCanApply(false, true);
+
+ parent_floater->addDependentFloater(mFloaterTexturePickerHandle);
+
+ texture_floaterp->openFloater();
+ texture_floaterp->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ floaterp->setMinimized(FALSE);
+ floaterp->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileFirstLife::onRemovePhoto()
+{
+ onCommitPhoto(LLUUID::null);
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+}
+
+void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id)
+{
+ if (mImageId == id)
+ {
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLSD params;
+ params["fl_image_id"] = id;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params));
+
+ mImageId = id;
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
+ }
+ else
+ {
+ mPicture->setValue("Generic_Person_Large");
+ }
+
+ mRemovePhoto->setEnabled(mImageId.notNull());
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileFirstLife::setDescriptionText(const std::string &text)
+{
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+
+ mCurrentDescription = text;
+ mDescriptionEdit->setValue(mCurrentDescription);
+}
+
+void LLPanelProfileFirstLife::onSetDescriptionDirty()
+{
+ mSaveChanges->setEnabled(TRUE);
+ mDiscardChanges->setEnabled(TRUE);
+ mHasUnsavedChanges = true;
+}
+
+void LLPanelProfileFirstLife::onSaveDescriptionChanges()
+{
+ mCurrentDescription = mDescriptionEdit->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+}
+
+void LLPanelProfileFirstLife::onDiscardDescriptionChanges()
+{
+ setDescriptionText(mCurrentDescription);
+}
+
+void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data)
+{
+ setDescriptionText(avatar_data->fl_about_text);
+
+ mImageId = avatar_data->fl_image_id;
+
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
+ }
+ else
+ {
+ mPicture->setValue("Generic_Person_Large");
+ }
+
+ setLoaded();
+}
+
+void LLPanelProfileFirstLife::resetData()
+{
+ setDescriptionText(std::string());
+ mPicture->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+
+ mUploadPhoto->setVisible(getSelfProfile());
+ mChangePhoto->setVisible(getSelfProfile());
+ mRemovePhoto->setVisible(getSelfProfile());
+ mSaveChanges->setVisible(getSelfProfile());
+ mDiscardChanges->setVisible(getSelfProfile());
+}
+
+void LLPanelProfileFirstLife::setLoaded()
+{
+ LLPanelProfileTab::setLoaded();
+
+ if (getSelfProfile())
+ {
+ mDescriptionEdit->setEnabled(TRUE);
+ mPicture->setEnabled(TRUE);
+ mRemovePhoto->setEnabled(mImageId.notNull());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelProfileNotes::LLPanelProfileNotes()
+: LLPanelProfileTab()
+ , mHasUnsavedChanges(false)
+{
+
+}
+
+LLPanelProfileNotes::~LLPanelProfileNotes()
+{
+}
+
+void LLPanelProfileNotes::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ }
+}
+
+void LLPanelProfileNotes::commitUnsavedChanges()
+{
+ if (mHasUnsavedChanges)
+ {
+ onSaveNotesChanges();
+ }
+}
+
+BOOL LLPanelProfileNotes::postBuild()
+{
+ mNotesEditor = getChild<LLTextEditor>("notes_edit");
+ mSaveChanges = getChild<LLButton>("notes_save_changes");
+ mDiscardChanges = getChild<LLButton>("notes_discard_changes");
+
+ mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveNotesChanges(); }, nullptr);
+ mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardNotesChanges(); }, nullptr);
+ mNotesEditor->setKeystrokeCallback([this](LLTextEditor* caller) { onSetNotesDirty(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileNotes::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+}
+
+void LLPanelProfileNotes::setNotesText(const std::string &text)
+{
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+
+ mCurrentNotes = text;
+ mNotesEditor->setValue(mCurrentNotes);
+}
+
+void LLPanelProfileNotes::onSetNotesDirty()
+{
+ mSaveChanges->setEnabled(TRUE);
+ mDiscardChanges->setEnabled(TRUE);
+ mHasUnsavedChanges = true;
+}
+
+void LLPanelProfileNotes::onSaveNotesChanges()
+{
+ mCurrentNotes = mNotesEditor->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+}
+
+void LLPanelProfileNotes::onDiscardNotesChanges()
+{
+ setNotesText(mCurrentNotes);
+}
+
+void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes)
+{
+ setNotesText(avatar_notes->notes);
+ mNotesEditor->setEnabled(TRUE);
+ setLoaded();
+}
+
+void LLPanelProfileNotes::resetData()
+{
+ resetLoading();
+ setNotesText(std::string());
+}
+
+void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfile
+
+LLPanelProfile::LLPanelProfile()
+ : LLPanelProfileTab()
+{
+}
+
+LLPanelProfile::~LLPanelProfile()
+{
+}
+
+BOOL LLPanelProfile::postBuild()
+{
+ return TRUE;
+}
+
+void LLPanelProfile::onTabChange()
+{
+ LLPanelProfileTab* active_panel = dynamic_cast<LLPanelProfileTab*>(mTabContainer->getCurrentPanel());
+ if (active_panel)
+ {
+ active_panel->updateData();
+ }
}
void LLPanelProfile::onOpen(const LLSD& key)
{
- getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId());
+ LLUUID avatar_id = key["id"].asUUID();
- // support commands to open further pieces of UI
- if (key.has("show_tab_panel"))
- {
- std::string panel = key["show_tab_panel"].asString();
- if (panel == "create_classified")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- picks->createNewClassified();
- }
- }
- else if (panel == "classified_details")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openClassifiedInfo(params);
- }
- }
- else if (panel == "edit_classified")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openClassifiedEdit(params);
- }
- }
- else if (panel == "create_pick")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- picks->createNewPick();
- }
- }
- else if (panel == "edit_pick")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openPickEdit(params);
- }
- }
- }
+ // Don't reload the same profile
+ if (getAvatarId() == avatar_id)
+ {
+ return;
+ }
+
+ LLPanelProfileTab::onOpen(avatar_id);
+
+ mTabContainer = getChild<LLTabContainer>("panel_profile_tabs");
+ mPanelSecondlife = findChild<LLPanelProfileSecondLife>(PANEL_SECONDLIFE);
+ mPanelWeb = findChild<LLPanelProfileWeb>(PANEL_WEB);
+ mPanelPicks = findChild<LLPanelProfilePicks>(PANEL_PICKS);
+ mPanelClassifieds = findChild<LLPanelProfileClassifieds>(PANEL_CLASSIFIEDS);
+ mPanelFirstlife = findChild<LLPanelProfileFirstLife>(PANEL_FIRSTLIFE);
+ mPanelNotes = findChild<LLPanelProfileNotes>(PANEL_NOTES);
+
+ mPanelSecondlife->onOpen(avatar_id);
+ mPanelWeb->onOpen(avatar_id);
+ mPanelPicks->onOpen(avatar_id);
+ mPanelClassifieds->onOpen(avatar_id);
+ mPanelFirstlife->onOpen(avatar_id);
+ mPanelNotes->onOpen(avatar_id);
+
+ // Always request the base profile info
+ resetLoading();
+ updateData();
+
+ // Some tabs only request data when opened
+ mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this));
}
-void LLPanelProfile::onTabSelected(const LLSD& param)
+void LLPanelProfile::updateData()
{
- std::string tab_name = param.asString();
- if (NULL != getTabContainer()[tab_name])
- {
- getTabContainer()[tab_name]->onOpen(getAvatarId());
- }
+ LLUUID avatar_id = getAvatarId();
+ // Todo: getIsloading functionality needs to be expanded to
+ // include 'inited' or 'data_provided' state to not rerequest
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ mPanelSecondlife->setIsLoading();
+ mPanelPicks->setIsLoading();
+ mPanelFirstlife->setIsLoading();
+ mPanelNotes->setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ }
}
-void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
+void LLPanelProfile::refreshName()
{
- // Hide currently visible panel (STORM-690).
- mChildStack.push();
+ mPanelSecondlife->refreshName();
+}
- // Add the panel or bring it to front.
- if (panel->getParent() != this)
- {
- addChild(panel);
- }
- else
- {
- sendChildToFront(panel);
- }
+void LLPanelProfile::createPick(const LLPickData &data)
+{
+ mTabContainer->selectTabPanel(mPanelPicks);
+ mPanelPicks->createPick(data);
+}
- panel->setVisible(TRUE);
- panel->setFocus(TRUE); // prevent losing focus by the floater
- panel->onOpen(params);
+void LLPanelProfile::showPick(const LLUUID& pick_id)
+{
+ if (pick_id.notNull())
+ {
+ mPanelPicks->selectPick(pick_id);
+ }
+ mTabContainer->selectTabPanel(mPanelPicks);
+}
- LLRect new_rect = getRect();
- panel->reshape(new_rect.getWidth(), new_rect.getHeight());
- new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
- panel->setRect(new_rect);
+bool LLPanelProfile::isPickTabSelected()
+{
+ return (mTabContainer->getCurrentPanel() == mPanelPicks);
}
-void LLPanelProfile::closePanel(LLPanel* panel)
+bool LLPanelProfile::isNotesTabSelected()
{
- panel->setVisible(FALSE);
+ return (mTabContainer->getCurrentPanel() == mPanelNotes);
+}
- if (panel->getParent() == this)
- {
- removeChild(panel);
+bool LLPanelProfile::hasUnsavedChanges()
+{
+ return mPanelSecondlife->hasUnsavedChanges()
+ || mPanelPicks->hasUnsavedChanges()
+ || mPanelClassifieds->hasUnsavedChanges()
+ || mPanelFirstlife->hasUnsavedChanges()
+ || mPanelNotes->hasUnsavedChanges();
+}
- // Make the underlying panel visible.
- mChildStack.pop();
+bool LLPanelProfile::hasUnpublishedClassifieds()
+{
+ return mPanelClassifieds->hasNewClassifieds();
+}
- // Prevent losing focus by the floater
- const child_list_t* child_list = getChildList();
- if (child_list->size() > 0)
- {
- child_list->front()->setFocus(TRUE);
- }
- else
- {
- LL_WARNS() << "No underlying panel to focus." << LL_ENDL;
- }
- }
+void LLPanelProfile::commitUnsavedChanges()
+{
+ mPanelSecondlife->commitUnsavedChanges();
+ mPanelPicks->commitUnsavedChanges();
+ mPanelClassifieds->commitUnsavedChanges();
+ mPanelFirstlife->commitUnsavedChanges();
+ mPanelNotes->commitUnsavedChanges();
}
-S32 LLPanelProfile::notifyParent(const LLSD& info)
+void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit)
{
- std::string action = info["action"];
- // lets update Picks list after Pick was saved
- if("save_new_pick" == action)
- {
- onOpen(info);
- return 1;
- }
+ if (classified_id.notNull())
+ {
+ mPanelClassifieds->selectClassified(classified_id, edit);
+ }
+ mTabContainer->selectTabPanel(mPanelClassifieds);
+}
- return LLPanel::notifyParent(info);
+void LLPanelProfile::createClassified()
+{
+ mPanelClassifieds->createClassified();
+ mTabContainer->selectTabPanel(mPanelClassifieds);
}
+
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index d97f60ed22..d32bb943bd 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelprofile.h
* @brief Profile panel
*
-* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
+* Copyright (C) 2022, 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$
*/
@@ -27,76 +27,383 @@
#ifndef LL_LLPANELPROFILE_H
#define LL_LLPANELPROFILE_H
+#include "llavatarpropertiesprocessor.h"
+#include "llcallingcard.h"
+#include "llfloater.h"
#include "llpanel.h"
#include "llpanelavatar.h"
+#include "llmediactrl.h"
+#include "llvoiceclient.h"
+
+// class LLPanelProfileClassifieds;
+// class LLTabContainer;
+// class LLPanelProfileSecondLife;
+// class LLPanelProfileWeb;
+// class LLPanelProfilePicks;
+// class LLPanelProfileFirstLife;
+// class LLPanelProfileNotes;
+
+class LLAvatarName;
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLIconCtrl;
class LLTabContainer;
+class LLTextBox;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLGroupList;
+class LLTextBase;
+class LLMenuButton;
+class LLLineEditor;
+class LLTextEditor;
+class LLPanelProfileClassifieds;
+class LLPanelProfilePicks;
+class LLViewerFetchedTexture;
-std::string getProfileURL(const std::string& agent_name);
/**
-* Base class for Profile View and My Profile.
+* Panel for displaying Avatar's second life related info.
*/
-class LLPanelProfile : public LLPanel
+class LLPanelProfileSecondLife
+ : public LLPanelProfileTab
+ , public LLFriendObserver
+ , public LLVoiceClientStatusObserver
{
- LOG_CLASS(LLPanelProfile);
+public:
+ LLPanelProfileSecondLife();
+ /*virtual*/ ~LLPanelProfileSecondLife();
+
+ void onOpen(const LLSD& key) override;
+
+ /**
+ * LLFriendObserver trigger
+ */
+ void changed(U32 mask) override;
+
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ void onChange(EStatusType status, const std::string &channelURI, bool proximal) override;
+
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ BOOL postBuild() override;
+
+ void resetData() override;
+
+ /**
+ * Sends update data request to server.
+ */
+ void updateData() override;
+ void refreshName();
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ void setProfileImageUploading(bool loading);
+ void setProfileImageUploaded(const LLUUID &image_asset_id);
+
+ bool hasUnsavedChanges() override;
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+protected:
+ /**
+ * Process profile related data received from server.
+ */
+ void processProfileProperties(const LLAvatarData* avatar_data);
+
+ /**
+ * Processes group related data received from server.
+ */
+ void processGroupProperties(const LLAvatarGroups* avatar_groups);
+
+ /**
+ * Fills common for Avatar profile and My Profile fields.
+ */
+ void fillCommonData(const LLAvatarData* avatar_data);
+
+ /**
+ * Fills partner data.
+ */
+ void fillPartnerData(const LLAvatarData* avatar_data);
+ /**
+ * Fills account status.
+ */
+ void fillAccountStatus(const LLAvatarData* avatar_data);
+
+ /**
+ * Sets permissions specific icon
+ */
+ void fillRightsData();
+
+ /**
+ * Fills user name, display name, age.
+ */
+ void fillAgeData(const LLDate &born_on);
+
+ void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep);
+ static void onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ /**
+ * Displays avatar's online status if possible.
+ *
+ * Requirements from EXT-3880:
+ * For friends:
+ * - Online when online and privacy settings allow to show
+ * - Offline when offline and privacy settings allow to show
+ * - Else: nothing
+ * For other avatars:
+ * - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online"
+ * - Else: Offline
+ */
+ void updateOnlineStatus();
+ void processOnlineStatus(bool is_friend, bool show_online, bool online);
+
+private:
+ void setLoaded() override;
+ void onCommitMenu(const LLSD& userdata);
+ bool onEnableMenu(const LLSD& userdata);
+ bool onCheckMenu(const LLSD& userdata);
+ void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name);
+
+ void setDescriptionText(const std::string &text);
+ void onSetDescriptionDirty();
+ void onShowInSearchCallback();
+ void onSaveDescriptionChanges();
+ void onDiscardDescriptionChanges();
+ void onShowAgentPermissionsDialog();
+ void onShowAgentProfileTexture();
+ void onShowTexturePicker();
+ void onCommitProfileImage(const LLUUID& id);
+
+private:
+ typedef std::map<std::string, LLUUID> group_map_t;
+ group_map_t mGroups;
+ void openGroupProfile();
+
+ LLGroupList* mGroupList;
+ LLComboBox* mShowInSearchCombo;
+ LLIconCtrl* mSecondLifePic;
+ LLPanel* mSecondLifePicLayout;
+ LLTextEditor* mDescriptionEdit;
+ LLMenuButton* mAgentActionMenuButton;
+ LLButton* mSaveDescriptionChanges;
+ LLButton* mDiscardDescriptionChanges;
+ LLIconCtrl* mCanSeeOnlineIcon;
+ LLIconCtrl* mCantSeeOnlineIcon;
+ LLIconCtrl* mCanSeeOnMapIcon;
+ LLIconCtrl* mCantSeeOnMapIcon;
+ LLIconCtrl* mCanEditObjectsIcon;
+ LLIconCtrl* mCantEditObjectsIcon;
+
+ LLHandle<LLFloater> mFloaterPermissionsHandle;
+ LLHandle<LLFloater> mFloaterProfileTextureHandle;
+ LLHandle<LLFloater> mFloaterTexturePickerHandle;
+
+ bool mHasUnsavedDescriptionChanges;
+ bool mVoiceStatus;
+ bool mWaitingForImageUpload;
+ bool mAllowPublish;
+ std::string mDescriptionText;
+ LLUUID mImageId;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+
+/**
+* Panel for displaying Avatar's web profile and home page.
+*/
+class LLPanelProfileWeb
+ : public LLPanelProfileTab
+ , public LLViewerMediaObserver
+{
public:
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void onOpen(const LLSD& key);
+ LLPanelProfileWeb();
+ /*virtual*/ ~LLPanelProfileWeb();
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL postBuild() override;
- virtual void openPanel(LLPanel* panel, const LLSD& params);
+ void resetData() override;
- virtual void closePanel(LLPanel* panel);
+ /**
+ * Loads web profile.
+ */
+ void updateData() override;
- S32 notifyParent(const LLSD& info);
+ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
protected:
+ void onCommitLoad(LLUICtrl* ctrl);
- LLPanelProfile();
+private:
+ std::string mURLHome;
+ std::string mURLWebProfile;
+ LLMediaCtrl* mWebBrowser;
- virtual void onTabSelected(const LLSD& param);
+ LLFrameTimer mPerformanceTimer;
+ bool mFirstNavigate;
- const LLUUID& getAvatarId() { return mAvatarId; }
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+/**
+* Panel for displaying Avatar's first life related info.
+*/
+class LLPanelProfileFirstLife
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfileFirstLife();
+ /*virtual*/ ~LLPanelProfileFirstLife();
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL postBuild() override;
+
+ void processProperties(const LLAvatarData* avatar_data);
+
+ void resetData() override;
+
+ void setProfileImageUploading(bool loading);
+ void setProfileImageUploaded(const LLUUID &image_asset_id);
+
+ bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+protected:
+ void setLoaded() override;
+
+ void onUploadPhoto();
+ void onChangePhoto();
+ void onRemovePhoto();
+ void onCommitPhoto(const LLUUID& id);
+ void setDescriptionText(const std::string &text);
+ void onSetDescriptionDirty();
+ void onSaveDescriptionChanges();
+ void onDiscardDescriptionChanges();
+
+ LLTextEditor* mDescriptionEdit;
+ LLIconCtrl* mPicture;
+ LLButton* mUploadPhoto;
+ LLButton* mChangePhoto;
+ LLButton* mRemovePhoto;
+ LLButton* mSaveChanges;
+ LLButton* mDiscardChanges;
+
+ LLHandle<LLFloater> mFloaterTexturePickerHandle;
+
+ std::string mCurrentDescription;
+ LLUUID mImageId;
+ bool mHasUnsavedChanges;
+};
+
+/**
+ * Panel for displaying Avatar's notes and modifying friend's rights.
+ */
+class LLPanelProfileNotes
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfileNotes();
+ /*virtual*/ ~LLPanelProfileNotes();
- void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
+ void setAvatarId(const LLUUID& avatar_id) override;
- typedef std::map<std::string, LLPanelProfileTab*> profile_tabs_t;
+ void onOpen(const LLSD& key) override;
- profile_tabs_t& getTabContainer() { return mTabContainer; }
+ BOOL postBuild() override;
+
+ void processProperties(LLAvatarNotes* avatar_notes);
+
+ void resetData() override;
+
+ void updateData() override;
+
+ bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
+ void commitUnsavedChanges() override;
+
+protected:
+ void setNotesText(const std::string &text);
+ void onSetNotesDirty();
+ void onSaveNotesChanges();
+ void onDiscardNotesChanges();
+
+ LLTextEditor* mNotesEditor;
+ LLButton* mSaveChanges;
+ LLButton* mDiscardChanges;
+
+ std::string mCurrentNotes;
+ bool mHasUnsavedChanges;
+};
+
+
+/**
+* Container panel for the profile tabs
+*/
+class LLPanelProfile
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfile();
+ /*virtual*/ ~LLPanelProfile();
+
+ BOOL postBuild() override;
+
+ void updateData() override;
+ void refreshName();
+
+ void onOpen(const LLSD& key) override;
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ bool isNotesTabSelected();
+ bool hasUnsavedChanges() override;
+ bool hasUnpublishedClassifieds();
+ void commitUnsavedChanges() override;
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+ LLAvatarData getAvatarData() { return mAvatarData; };
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
private:
+ void onTabChange();
+
+ LLPanelProfileSecondLife* mPanelSecondlife;
+ LLPanelProfileWeb* mPanelWeb;
+ LLPanelProfilePicks* mPanelPicks;
+ LLPanelProfileClassifieds* mPanelClassifieds;
+ LLPanelProfileFirstLife* mPanelFirstlife;
+ LLPanelProfileNotes* mPanelNotes;
+ LLTabContainer* mTabContainer;
- //-- ChildStack begins ----------------------------------------------------
- class ChildStack
- {
- LOG_CLASS(LLPanelProfile::ChildStack);
- public:
- ChildStack();
- ~ChildStack();
- void setParent(LLPanel* parent);
-
- bool push();
- bool pop();
- void preParentReshape();
- void postParentReshape();
-
- private:
- void dump();
-
- typedef LLView::child_list_t view_list_t;
- typedef std::list<view_list_t> stack_t;
-
- stack_t mStack;
- stack_t mSavedStack;
- LLPanel* mParent;
- };
- //-- ChildStack ends ------------------------------------------------------
-
- profile_tabs_t mTabContainer;
- ChildStack mChildStack;
- LLUUID mAvatarId;
+ // Todo: due to server taking minutes to update this needs a more long term storage
+ // to reuse recently saved values if user opens floater again
+ // Storage implementation depends onto how a cap will be implemented, if cap will be
+ // enought to fully update LLAvatarPropertiesProcessor, then this storage can be
+ // implemented there.
+ LLAvatarData mAvatarData;
};
#endif //LL_LLPANELPROFILE_H
diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp
new file mode 100644
index 0000000000..a3913ddc49
--- /dev/null
+++ b/indra/newview/llpanelprofileclassifieds.cpp
@@ -0,0 +1,1513 @@
+/**
+ * @file llpanelprofileclassifieds.cpp
+ * @brief LLPanelProfileClassifieds and related class implementations
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelprofileclassifieds.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llclassifiedflags.h"
+#include "llcombobox.h"
+#include "llcommandhandler.h" // for classified HTML detail page click tracking
+#include "llcorehttputil.h"
+#include "lldispatcher.h"
+#include "llfloaterclassified.h"
+#include "llfloaterreg.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfloaterworldmap.h"
+#include "lliconctrl.h"
+#include "lllineeditor.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llparcel.h"
+#include "llregistry.h"
+#include "llscrollcontainer.h"
+#include "llstartup.h"
+#include "llstatusbar.h"
+#include "lltabcontainer.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llviewertexture.h"
+#include "llviewertexture.h"
+
+
+//*TODO: verify this limit
+const S32 MAX_AVATAR_CLASSIFIEDS = 100;
+
+const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
+const S32 DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT = 530;
+
+//static
+LLPanelProfileClassified::panel_list_t LLPanelProfileClassified::sAllPanels;
+
+static LLPanelInjector<LLPanelProfileClassifieds> t_panel_profile_classifieds("panel_profile_classifieds");
+static LLPanelInjector<LLPanelProfileClassified> t_panel_profile_classified("panel_profile_classified");
+
+class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesObserver
+{
+public:
+ // throttle calls from untrusted browsers
+ LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
+
+ std::set<LLUUID> mClassifiedIds;
+ std::string mRequestVerb;
+
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
+ if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
+ {
+ LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
+ // handle app/classified/create urls first
+ if (params.size() == 1 && params[0].asString() == "create")
+ {
+ LLAvatarActions::createClassified();
+ return true;
+ }
+
+ // then handle the general app/classified/{UUID}/{CMD} urls
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the classified
+ LLUUID classified_id;
+ if (!classified_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // show the classified in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "about")
+ {
+ mRequestVerb = verb;
+ mClassifiedIds.insert(classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
+ return true;
+ }
+ else if (verb == "edit")
+ {
+ LLAvatarActions::showClassified(gAgent.getID(), classified_id, true);
+ return true;
+ }
+
+ return false;
+ }
+
+ void openClassified(LLAvatarClassifiedInfo* c_info)
+ {
+ if (mRequestVerb == "about")
+ {
+ if (c_info->creator_id == gAgent.getID())
+ {
+ LLAvatarActions::showClassified(gAgent.getID(), c_info->classified_id, false);
+ }
+ else
+ {
+ LLSD params;
+ params["id"] = c_info->creator_id;
+ params["classified_id"] = c_info->classified_id;
+ params["classified_creator_id"] = c_info->creator_id;
+ params["classified_snapshot_id"] = c_info->snapshot_id;
+ params["classified_name"] = c_info->name;
+ params["classified_desc"] = c_info->description;
+ params["from_search"] = true;
+
+ LLFloaterClassified* floaterp = LLFloaterReg::getTypedInstance<LLFloaterClassified>("classified", params);
+ if (floaterp)
+ {
+ floaterp->openFloater(params);
+ floaterp->setVisibleAndFrontmost();
+ }
+ }
+ }
+ }
+
+ void processProperties(void* data, EAvatarProcessorType type)
+ {
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ // is this the classified that we asked for?
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
+ {
+ return;
+ }
+
+ // open the detail side tray for this classified
+ openClassified(c_info);
+
+ // remove our observer now that we're done
+ mClassifiedIds.erase(c_info->classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
+ }
+};
+LLClassifiedHandler gClassifiedHandler;
+
+//////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfileClassifieds
+//-----------------------------------------------------------------------------
+
+LLPanelProfileClassifieds::LLPanelProfileClassifieds()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mClassifiedToSelectOnLoad(LLUUID::null)
+ , mClassifiedEditOnLoad(false)
+ , mSheduledClassifiedCreation(false)
+{
+}
+
+LLPanelProfileClassifieds::~LLPanelProfileClassifieds()
+{
+}
+
+void LLPanelProfileClassifieds::onOpen(const LLSD& key)
+{
+ LLPanelProfilePropertiesProcessorTab::onOpen(key);
+
+ resetData();
+
+ bool own_profile = getSelfProfile();
+ if (own_profile)
+ {
+ mNewButton->setVisible(TRUE);
+ mNewButton->setEnabled(FALSE);
+
+ mDeleteButton->setVisible(TRUE);
+ mDeleteButton->setEnabled(FALSE);
+ }
+
+ childSetVisible("buttons_header", own_profile);
+
+}
+
+void LLPanelProfileClassifieds::selectClassified(const LLUUID& classified_id, bool edit)
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel)
+ {
+ if (classified_panel->getClassifiedId() == classified_id)
+ {
+ mTabContainer->selectTabPanel(classified_panel);
+ if (edit)
+ {
+ classified_panel->setEditMode(TRUE);
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ mClassifiedToSelectOnLoad = classified_id;
+ mClassifiedEditOnLoad = edit;
+ }
+}
+
+void LLPanelProfileClassifieds::createClassified()
+{
+ if (getIsLoaded())
+ {
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(true).
+ label(classified_panel->getClassifiedName()));
+ updateButtons();
+ }
+ else
+ {
+ mSheduledClassifiedCreation = true;
+ }
+}
+
+BOOL LLPanelProfileClassifieds::postBuild()
+{
+ mTabContainer = getChild<LLTabContainer>("tab_classifieds");
+ mNoItemsLabel = getChild<LLUICtrl>("classifieds_panel_text");
+ mNewButton = getChild<LLButton>("new_btn");
+ mDeleteButton = getChild<LLButton>("delete_btn");
+
+ mNewButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickNewBtn, this));
+ mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickDelete, this));
+
+ return TRUE;
+}
+
+void LLPanelProfileClassifieds::onClickNewBtn()
+{
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(true).
+ label(classified_panel->getClassifiedName()));
+ updateButtons();
+}
+
+void LLPanelProfileClassifieds::onClickDelete()
+{
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getCurrentPanel());
+ if (classified_panel)
+ {
+ LLUUID classified_id = classified_panel->getClassifiedId();
+ LLSD args;
+ args["CLASSIFIED"] = classified_panel->getClassifiedName();
+ LLSD payload;
+ payload["classified_id"] = classified_id;
+ payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
+ LLNotificationsUtil::add("ProfileDeleteClassified", args, payload,
+ boost::bind(&LLPanelProfileClassifieds::callbackDeleteClassified, this, _1, _2));
+ }
+}
+
+void LLPanelProfileClassifieds::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ LLUUID classified_id = notification["payload"]["classified_id"].asUUID();
+ S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
+
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->getClassifiedId() == classified_id)
+ {
+ mTabContainer->removeTabPanel(classified_panel);
+ }
+
+ if (classified_id.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedDelete(classified_id);
+ }
+
+ updateButtons();
+
+ BOOL no_data = !mTabContainer->getTabCount();
+ mNoItemsLabel->setVisible(no_data);
+ }
+}
+
+void LLPanelProfileClassifieds::processProperties(void* data, EAvatarProcessorType type)
+{
+ if ((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
+ {
+ LLUUID avatar_id = getAvatarId();
+
+ LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
+ if (c_info && getAvatarId() == c_info->target_id)
+ {
+ // do not clear classified list in case we will receive two or more data packets.
+ // list has been cleared in updateData(). (fix for EXT-6436)
+ LLUUID selected_id = mClassifiedToSelectOnLoad;
+ bool has_selection = false;
+
+ LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
+ for (; c_info->classifieds_list.end() != it; ++it)
+ {
+ LLAvatarClassifieds::classified_data c_data = *it;
+
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+
+ LLSD params;
+ params["classified_creator_id"] = avatar_id;
+ params["classified_id"] = c_data.classified_id;
+ params["classified_name"] = c_data.name;
+ params["from_search"] = (selected_id == c_data.classified_id); //SLURL handling and stats tracking
+ params["edit"] = (selected_id == c_data.classified_id) && mClassifiedEditOnLoad;
+ classified_panel->onOpen(params);
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(selected_id == c_data.classified_id).
+ label(c_data.name));
+
+ if (selected_id == c_data.classified_id)
+ {
+ has_selection = true;
+ }
+ }
+
+ if (mSheduledClassifiedCreation)
+ {
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(!has_selection).
+ label(classified_panel->getClassifiedName()));
+ has_selection = true;
+ }
+
+ // reset 'do on load' values
+ mClassifiedToSelectOnLoad = LLUUID::null;
+ mClassifiedEditOnLoad = false;
+ mSheduledClassifiedCreation = false;
+
+ // set even if not visible, user might delete own
+ // calassified and this string will need to be shown
+ if (getSelfProfile())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoClassifiedsText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarClassifiedsText"));
+ }
+
+ bool has_data = mTabContainer->getTabCount() > 0;
+ mNoItemsLabel->setVisible(!has_data);
+ if (has_data && !has_selection)
+ {
+ mTabContainer->selectFirstTab();
+ }
+
+ setLoaded();
+ updateButtons();
+ }
+ }
+}
+
+void LLPanelProfileClassifieds::resetData()
+{
+ resetLoading();
+ mTabContainer->deleteAllTabs();
+}
+
+void LLPanelProfileClassifieds::updateButtons()
+{
+ if (getSelfProfile())
+ {
+ mNewButton->setEnabled(canAddNewClassified());
+ mDeleteButton->setEnabled(canDeleteClassified());
+ }
+}
+
+void LLPanelProfileClassifieds::updateData()
+{
+ // Send picks request only once
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+ mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+ mNoItemsLabel->setVisible(TRUE);
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(avatar_id);
+ }
+}
+
+bool LLPanelProfileClassifieds::hasNewClassifieds()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isNew())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLPanelProfileClassifieds::hasUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isDirty()) // includes 'new'
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLPanelProfileClassifieds::canAddNewClassified()
+{
+ return (mTabContainer->getTabCount() < MAX_AVATAR_CLASSIFIEDS);
+}
+
+bool LLPanelProfileClassifieds::canDeleteClassified()
+{
+ return (mTabContainer->getTabCount() > 0);
+}
+
+void LLPanelProfileClassifieds::commitUnsavedChanges()
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isDirty() && !classified_panel->isNew())
+ {
+ classified_panel->doSave();
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+// LLDispatchClassifiedClickThrough
+//-----------------------------------------------------------------------------
+
+// "classifiedclickthrough"
+// strings[0] = classified_id
+// strings[1] = teleport_clicks
+// strings[2] = map_clicks
+// strings[3] = profile_clicks
+class LLDispatchClassifiedClickThrough : public LLDispatchHandler
+{
+public:
+ virtual bool operator()(
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings)
+ {
+ if (strings.size() != 4) return false;
+ LLUUID classified_id(strings[0]);
+ S32 teleport_clicks = atoi(strings[1].c_str());
+ S32 map_clicks = atoi(strings[2].c_str());
+ S32 profile_clicks = atoi(strings[3].c_str());
+
+ LLPanelProfileClassified::setClickThrough(
+ classified_id, teleport_clicks, map_clicks, profile_clicks, false);
+
+ return true;
+ }
+};
+static LLDispatchClassifiedClickThrough sClassifiedClickThrough;
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfileClassified
+//-----------------------------------------------------------------------------
+
+static const S32 CB_ITEM_MATURE = 0;
+static const S32 CB_ITEM_PG = 1;
+
+LLPanelProfileClassified::LLPanelProfileClassified()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mInfoLoaded(false)
+ , mTeleportClicksOld(0)
+ , mMapClicksOld(0)
+ , mProfileClicksOld(0)
+ , mTeleportClicksNew(0)
+ , mMapClicksNew(0)
+ , mProfileClicksNew(0)
+ , mPriceForListing(0)
+ , mSnapshotCtrl(NULL)
+ , mPublishFloater(NULL)
+ , mIsNew(false)
+ , mIsNewWithErrors(false)
+ , mCanClose(false)
+ , mEditMode(false)
+ , mEditOnLoad(false)
+{
+ sAllPanels.push_back(this);
+}
+
+LLPanelProfileClassified::~LLPanelProfileClassified()
+{
+ sAllPanels.remove(this);
+ gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
+}
+
+//static
+LLPanelProfileClassified* LLPanelProfileClassified::create()
+{
+ LLPanelProfileClassified* panel = new LLPanelProfileClassified();
+ panel->buildFromFile("panel_profile_classified.xml");
+ return panel;
+}
+
+BOOL LLPanelProfileClassified::postBuild()
+{
+ mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
+ mInfoPanel = getChild<LLView>("info_panel");
+ mInfoScroll = getChild<LLPanel>("info_scroll_content_panel");
+ mEditPanel = getChild<LLPanel>("edit_panel");
+
+ mSnapshotCtrl = getChild<LLTextureCtrl>("classified_snapshot");
+ mEditIcon = getChild<LLUICtrl>("edit_icon");
+
+ //info
+ mClassifiedNameText = getChild<LLUICtrl>("classified_name");
+ mClassifiedDescText = getChild<LLTextEditor>("classified_desc");
+ mLocationText = getChild<LLUICtrl>("classified_location");
+ mCategoryText = getChild<LLUICtrl>("category");
+ mContentTypeText = getChild<LLUICtrl>("content_type");
+ mContentTypeM = getChild<LLIconCtrl>("content_type_moderate");
+ mContentTypeG = getChild<LLIconCtrl>("content_type_general");
+ mPriceText = getChild<LLUICtrl>("price_for_listing");
+ mAutoRenewText = getChild<LLUICtrl>("auto_renew");
+
+ mMapButton = getChild<LLButton>("show_on_map_btn");
+ mTeleportButton = getChild<LLButton>("teleport_btn");
+ mEditButton = getChild<LLButton>("edit_btn");
+
+ //edit
+ mClassifiedNameEdit = getChild<LLLineEditor>("classified_name_edit");
+ mClassifiedDescEdit = getChild<LLTextEditor>("classified_desc_edit");
+ mLocationEdit = getChild<LLUICtrl>("classified_location_edit");
+ mCategoryCombo = getChild<LLComboBox>("category_edit");
+ mContentTypeCombo = getChild<LLComboBox>("content_type_edit");
+ mAutoRenewEdit = getChild<LLUICtrl>("auto_renew_edit");
+
+ mSaveButton = getChild<LLButton>("save_changes_btn");
+ mSetLocationButton = getChild<LLButton>("set_to_curr_location_btn");
+ mCancelButton = getChild<LLButton>("cancel_btn");
+
+ mUtilityBtnCnt = getChild<LLPanel>("util_buttons_lp");
+ mPublishBtnsCnt = getChild<LLPanel>("publish_layout_panel");
+ mCancelBtnCnt = getChild<LLPanel>("cancel_btn_lp");
+ mSaveBtnCnt = getChild<LLPanel>("save_btn_lp");
+
+ mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelProfileClassified::onTextureSelected, this));
+ mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseEnter, this));
+ mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseLeave, this));
+ mEditIcon->setVisible(false);
+
+ mMapButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onMapClick, this));
+ mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onTeleportClick, this));
+ mEditButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onEditClick, this));
+ mSaveButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSaveClick, this));
+ mSetLocationButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSetLocationClick, this));
+ mCancelButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onCancelClick, this));
+
+ LLClassifiedInfo::cat_map::iterator iter;
+ for (iter = LLClassifiedInfo::sCategories.begin();
+ iter != LLClassifiedInfo::sCategories.end();
+ iter++)
+ {
+ mCategoryCombo->add(LLTrans::getString(iter->second));
+ }
+
+ mClassifiedNameEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this), NULL);
+ mClassifiedDescEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mCategoryCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mContentTypeCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mAutoRenewEdit->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+
+ return TRUE;
+}
+
+void LLPanelProfileClassified::onOpen(const LLSD& key)
+{
+ mIsNew = key.isUndefined();
+
+ resetData();
+ resetControls();
+ scrollToTop();
+
+ // classified is not created yet
+ bool is_new = isNew() || isNewWithErrors();
+
+ if(is_new)
+ {
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(gAgent.getID());
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID snapshot_id = LLUUID::null;
+ std::string desc;
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedName(makeClassifiedName());
+ setDescription(desc);
+ setSnapshotId(snapshot_id);
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+ // server will set valid parcel id
+ setParcelId(LLUUID::null);
+
+ mSaveButton->setLabelArg("[LABEL]", getString("publish_label"));
+
+ setEditMode(TRUE);
+ enableSave(true);
+ enableEditing(true);
+ resetDirty();
+ setInfoLoaded(false);
+ }
+ else
+ {
+ LLUUID avatar_id = key["classified_creator_id"];
+ if(avatar_id.isNull())
+ {
+ return;
+ }
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
+
+ setClassifiedId(key["classified_id"]);
+ setClassifiedName(key["classified_name"]);
+ setFromSearch(key["from_search"]);
+ mEditOnLoad = key["edit"];
+
+ LL_INFOS() << "Opening classified [" << getClassifiedName() << "] (" << getClassifiedId() << ")" << LL_ENDL;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+
+ gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough);
+
+ if (gAgent.getRegion())
+ {
+ // While we're at it let's get the stats from the new table if that
+ // capability exists.
+ std::string url = gAgent.getRegion()->getCapability("SearchStatRequest");
+ if (!url.empty())
+ {
+ LL_INFOS() << "Classified stat request via capability" << LL_ENDL;
+ LLSD body;
+ LLUUID classifiedId = getClassifiedId();
+ body["classified_id"] = classifiedId;
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body,
+ boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, classifiedId, _1));
+ }
+ }
+ // Update classified click stats.
+ // *TODO: Should we do this when opening not from search?
+ if (!fromSearch() )
+ {
+ sendClickMessage("profile");
+ }
+
+ setInfoLoaded(false);
+ }
+
+
+ bool is_self = getSelfProfile();
+ getChildView("auto_renew_layout_panel")->setVisible(is_self);
+ getChildView("clickthrough_layout_panel")->setVisible(is_self);
+
+ updateButtons();
+}
+
+void LLPanelProfileClassified::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if(c_info && getClassifiedId() == c_info->classified_id)
+ {
+ // see LLPanelProfileClassified::sendUpdate() for notes
+ if (mIsNewWithErrors)
+ {
+ // We just published it
+ setEditMode(FALSE);
+ }
+ mIsNewWithErrors = false;
+ mIsNew = false;
+
+ setClassifiedName(c_info->name);
+ setDescription(c_info->description);
+ setSnapshotId(c_info->snapshot_id);
+ setParcelId(c_info->parcel_id);
+ setPosGlobal(c_info->pos_global);
+ setSimName(c_info->sim_name);
+
+ setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
+
+ mCategoryText->setValue(LLClassifiedInfo::sCategories[c_info->category]);
+ // *HACK see LLPanelProfileClassified::sendUpdate()
+ setCategory(c_info->category - 1);
+
+ bool mature = is_cf_mature(c_info->flags);
+ setContentType(mature);
+
+ bool auto_renew = is_cf_auto_renew(c_info->flags);
+ std::string auto_renew_str = auto_renew ? getString("auto_renew_on") : getString("auto_renew_off");
+ mAutoRenewText->setValue(auto_renew_str);
+ mAutoRenewEdit->setValue(auto_renew);
+
+ static LLUIString price_str = getString("l$_price");
+ price_str.setArg("[PRICE]", llformat("%d", c_info->price_for_listing));
+ mPriceText->setValue(LLSD(price_str));
+
+ static std::string date_fmt = getString("date_fmt");
+ std::string date_str = date_fmt;
+ LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->creation_date));
+ getChild<LLUICtrl>("creation_date")->setValue(date_str);
+
+ resetDirty();
+ setInfoLoaded(true);
+ enableSave(false);
+ enableEditing(true);
+
+ // for just created classified - in case user opened edit panel before processProperties() callback
+ mSaveButton->setLabelArg("[LABEL]", getString("save_label"));
+
+ setLoaded();
+ updateButtons();
+
+ if (mEditOnLoad)
+ {
+ setEditMode(TRUE);
+ }
+ }
+
+}
+
+void LLPanelProfileClassified::setEditMode(BOOL edit_mode)
+{
+ mEditMode = edit_mode;
+
+ mInfoPanel->setVisible(!edit_mode);
+ mEditPanel->setVisible(edit_mode);
+
+ // snapshot control is common between info and edit,
+ // enable it only when in edit mode
+ mSnapshotCtrl->setEnabled(edit_mode);
+
+ scrollToTop();
+ updateButtons();
+ updateInfoRect();
+}
+
+void LLPanelProfileClassified::updateButtons()
+{
+ bool edit_mode = getEditMode();
+ mUtilityBtnCnt->setVisible(!edit_mode);
+
+ // cancel button should either delete unpublished
+ // classified or not be there at all
+ mCancelBtnCnt->setVisible(edit_mode && !mIsNew);
+ mPublishBtnsCnt->setVisible(edit_mode);
+ mSaveBtnCnt->setVisible(edit_mode);
+ mEditButton->setVisible(!edit_mode && getSelfProfile());
+}
+
+void LLPanelProfileClassified::updateInfoRect()
+{
+ if (getEditMode())
+ {
+ // info_scroll_content_panel contains both info and edit panel
+ // info panel can be very large and scroll bar will carry over.
+ // Resize info panel to prevent scroll carry over when in edit mode.
+ mInfoScroll->reshape(mInfoScroll->getRect().getWidth(), DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT, FALSE);
+ }
+ else
+ {
+ // Adjust text height to make description scrollable.
+ S32 new_height = mClassifiedDescText->getTextBoundingRect().getHeight();
+ LLRect visible_rect = mClassifiedDescText->getVisibleDocumentRect();
+ S32 delta_height = new_height - visible_rect.getHeight() + 5;
+
+ LLRect rect = mInfoScroll->getRect();
+ mInfoScroll->reshape(rect.getWidth(), rect.getHeight() + delta_height, FALSE);
+ }
+}
+
+void LLPanelProfileClassified::enableEditing(bool enable)
+{
+ mEditButton->setEnabled(enable);
+ mClassifiedNameEdit->setEnabled(enable);
+ mClassifiedDescEdit->setEnabled(enable);
+ mSetLocationButton->setEnabled(enable);
+ mCategoryCombo->setEnabled(enable);
+ mContentTypeCombo->setEnabled(enable);
+ mAutoRenewEdit->setEnabled(enable);
+}
+
+void LLPanelProfileClassified::resetControls()
+{
+ updateButtons();
+
+ mCategoryCombo->setCurrentByIndex(0);
+ mContentTypeCombo->setCurrentByIndex(0);
+ mAutoRenewEdit->setValue(false);
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+}
+
+void LLPanelProfileClassified::onEditClick()
+{
+ setEditMode(TRUE);
+}
+
+void LLPanelProfileClassified::onCancelClick()
+{
+ if (isNew())
+ {
+ mClassifiedNameEdit->setValue(mClassifiedNameText->getValue());
+ mClassifiedDescEdit->setValue(mClassifiedDescText->getValue());
+ mLocationEdit->setValue(mLocationText->getValue());
+ mCategoryCombo->setCurrentByIndex(0);
+ mContentTypeCombo->setCurrentByIndex(0);
+ mAutoRenewEdit->setValue(false);
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+ }
+ else
+ {
+ // Reload data to undo changes to forms
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+ }
+
+ setInfoLoaded(false);
+
+ setEditMode(FALSE);
+}
+
+void LLPanelProfileClassified::onSaveClick()
+{
+ mCanClose = false;
+
+ if(!isValidName())
+ {
+ notifyInvalidName();
+ return;
+ }
+ if(isNew() || isNewWithErrors())
+ {
+ if(gStatusBar->getBalance() < getPriceForListing())
+ {
+ LLNotificationsUtil::add("ClassifiedInsufficientFunds");
+ return;
+ }
+
+ mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
+ "publish_classified", LLSD());
+
+ if(!mPublishFloater)
+ {
+ mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
+ "publish_classified", LLSD());
+
+ mPublishFloater->setPublishClickedCallback(boost::bind
+ (&LLPanelProfileClassified::onPublishFloaterPublishClicked, this));
+ }
+
+ // set spinner value before it has focus or value wont be set
+ mPublishFloater->setPrice(getPriceForListing());
+ mPublishFloater->openFloater(mPublishFloater->getKey());
+ mPublishFloater->center();
+ }
+ else
+ {
+ doSave();
+ }
+}
+
+/*static*/
+void LLPanelProfileClassified::handleSearchStatResponse(LLUUID classifiedId, LLSD result)
+{
+ S32 teleport = result["teleport_clicks"].asInteger();
+ S32 map = result["map_clicks"].asInteger();
+ S32 profile = result["profile_clicks"].asInteger();
+ S32 search_teleport = result["search_teleport_clicks"].asInteger();
+ S32 search_map = result["search_map_clicks"].asInteger();
+ S32 search_profile = result["search_profile_clicks"].asInteger();
+
+ LLPanelProfileClassified::setClickThrough(classifiedId,
+ teleport + search_teleport,
+ map + search_map,
+ profile + search_profile,
+ true);
+}
+
+void LLPanelProfileClassified::resetData()
+{
+ setClassifiedName(LLStringUtil::null);
+ setDescription(LLStringUtil::null);
+ setClassifiedLocation(LLStringUtil::null);
+ setClassifiedId(LLUUID::null);
+ setSnapshotId(LLUUID::null);
+ setPosGlobal(LLVector3d::zero);
+ setParcelId(LLUUID::null);
+ setSimName(LLStringUtil::null);
+ setFromSearch(false);
+
+ // reset click stats
+ mTeleportClicksOld = 0;
+ mMapClicksOld = 0;
+ mProfileClicksOld = 0;
+ mTeleportClicksNew = 0;
+ mMapClicksNew = 0;
+ mProfileClicksNew = 0;
+
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+
+ mCategoryText->setValue(LLStringUtil::null);
+ mContentTypeText->setValue(LLStringUtil::null);
+ getChild<LLUICtrl>("click_through_text")->setValue(LLStringUtil::null);
+ mEditButton->setValue(LLStringUtil::null);
+ getChild<LLUICtrl>("creation_date")->setValue(LLStringUtil::null);
+ mContentTypeM->setVisible(FALSE);
+ mContentTypeG->setVisible(FALSE);
+}
+
+void LLPanelProfileClassified::setClassifiedName(const std::string& name)
+{
+ mClassifiedNameText->setValue(name);
+ mClassifiedNameEdit->setValue(name);
+}
+
+std::string LLPanelProfileClassified::getClassifiedName()
+{
+ return mClassifiedNameEdit->getValue().asString();
+}
+
+void LLPanelProfileClassified::setDescription(const std::string& desc)
+{
+ mClassifiedDescText->setValue(desc);
+ mClassifiedDescEdit->setValue(desc);
+
+ updateInfoRect();
+}
+
+std::string LLPanelProfileClassified::getDescription()
+{
+ return mClassifiedDescEdit->getValue().asString();
+}
+
+void LLPanelProfileClassified::setClassifiedLocation(const std::string& location)
+{
+ mLocationText->setValue(location);
+ mLocationEdit->setValue(location);
+}
+
+std::string LLPanelProfileClassified::getClassifiedLocation()
+{
+ return mLocationText->getValue().asString();
+}
+
+void LLPanelProfileClassified::setSnapshotId(const LLUUID& id)
+{
+ mSnapshotCtrl->setValue(id);
+}
+
+LLUUID LLPanelProfileClassified::getSnapshotId()
+{
+ return mSnapshotCtrl->getValue().asUUID();
+}
+
+// static
+void LLPanelProfileClassified::setClickThrough(
+ const LLUUID& classified_id,
+ S32 teleport,
+ S32 map,
+ S32 profile,
+ bool from_new_table)
+{
+ LL_INFOS() << "Click-through data for classified " << classified_id << " arrived: ["
+ << teleport << ", " << map << ", " << profile << "] ("
+ << (from_new_table ? "new" : "old") << ")" << LL_ENDL;
+
+ for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
+ {
+ LLPanelProfileClassified* self = *iter;
+ if (self->getClassifiedId() != classified_id)
+ {
+ continue;
+ }
+
+ // *HACK: Skip LLPanelProfileClassified instances: they don't display clicks data.
+ // Those instances should not be in the list at all.
+ if (typeid(*self) != typeid(LLPanelProfileClassified))
+ {
+ continue;
+ }
+
+ LL_INFOS() << "Updating classified info panel" << LL_ENDL;
+
+ // We need to check to see if the data came from the new stat_table
+ // or the old classified table. We also need to cache the data from
+ // the two separate sources so as to display the aggregate totals.
+
+ if (from_new_table)
+ {
+ self->mTeleportClicksNew = teleport;
+ self->mMapClicksNew = map;
+ self->mProfileClicksNew = profile;
+ }
+ else
+ {
+ self->mTeleportClicksOld = teleport;
+ self->mMapClicksOld = map;
+ self->mProfileClicksOld = profile;
+ }
+
+ static LLUIString ct_str = self->getString("click_through_text_fmt");
+
+ ct_str.setArg("[TELEPORT]", llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld));
+ ct_str.setArg("[MAP]", llformat("%d", self->mMapClicksNew + self->mMapClicksOld));
+ ct_str.setArg("[PROFILE]", llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld));
+
+ self->getChild<LLUICtrl>("click_through_text")->setValue(ct_str.getString());
+ // *HACK: remove this when there is enough room for click stats in the info panel
+ self->getChildView("click_through_text")->setToolTip(ct_str.getString());
+
+ LL_INFOS() << "teleport: " << llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld)
+ << ", map: " << llformat("%d", self->mMapClicksNew + self->mMapClicksOld)
+ << ", profile: " << llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld)
+ << LL_ENDL;
+ }
+}
+
+// static
+std::string LLPanelProfileClassified::createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global)
+{
+ std::string location_text;
+
+ location_text.append(original_name);
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ location_text.append(", ");
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ location_text.append(" ");
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+
+ return location_text;
+}
+
+void LLPanelProfileClassified::scrollToTop()
+{
+ if (mScrollContainer)
+ {
+ mScrollContainer->goToTop();
+ }
+}
+
+//info
+// static
+// *TODO: move out of the panel
+void LLPanelProfileClassified::sendClickMessage(
+ const std::string& type,
+ bool from_search,
+ const LLUUID& classified_id,
+ const LLUUID& parcel_id,
+ const LLVector3d& global_pos,
+ const std::string& sim_name)
+{
+ if (gAgent.getRegion())
+ {
+ // You're allowed to click on your own ads to reassure yourself
+ // that the system is working.
+ LLSD body;
+ body["type"] = type;
+ body["from_search"] = from_search;
+ body["classified_id"] = classified_id;
+ body["parcel_id"] = parcel_id;
+ body["dest_pos_global"] = global_pos.getValue();
+ body["region_name"] = sim_name;
+
+ std::string url = gAgent.getRegion()->getCapability("SearchStatTracking");
+ LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL;
+ LL_INFOS() << "body: [" << body << "]" << LL_ENDL;
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent.");
+ }
+}
+
+void LLPanelProfileClassified::sendClickMessage(const std::string& type)
+{
+ sendClickMessage(
+ type,
+ fromSearch(),
+ getClassifiedId(),
+ getParcelId(),
+ getPosGlobal(),
+ getSimName());
+}
+
+void LLPanelProfileClassified::onMapClick()
+{
+ sendClickMessage("map");
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfileClassified::onTeleportClick()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ sendClickMessage("teleport");
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+BOOL LLPanelProfileClassified::isDirty() const
+{
+ if(mIsNew)
+ {
+ return TRUE;
+ }
+
+ BOOL dirty = false;
+ dirty |= mSnapshotCtrl->isDirty();
+ dirty |= mClassifiedNameEdit->isDirty();
+ dirty |= mClassifiedDescEdit->isDirty();
+ dirty |= mCategoryCombo->isDirty();
+ dirty |= mContentTypeCombo->isDirty();
+ dirty |= mAutoRenewEdit->isDirty();
+
+ return dirty;
+}
+
+void LLPanelProfileClassified::resetDirty()
+{
+ mSnapshotCtrl->resetDirty();
+ mClassifiedNameEdit->resetDirty();
+
+ // call blockUndo() to really reset dirty(and make isDirty work as intended)
+ mClassifiedDescEdit->blockUndo();
+ mClassifiedDescEdit->resetDirty();
+
+ mCategoryCombo->resetDirty();
+ mContentTypeCombo->resetDirty();
+ mAutoRenewEdit->resetDirty();
+}
+
+bool LLPanelProfileClassified::canClose()
+{
+ return mCanClose;
+}
+
+U32 LLPanelProfileClassified::getContentType()
+{
+ return mContentTypeCombo->getCurrentIndex();
+}
+
+void LLPanelProfileClassified::setContentType(bool mature)
+{
+ static std::string mature_str = getString("type_mature");
+ static std::string pg_str = getString("type_pg");
+ mContentTypeText->setValue(mature ? mature_str : pg_str);
+ mContentTypeM->setVisible(mature);
+ mContentTypeG->setVisible(!mature);
+ mContentTypeCombo->setCurrentByIndex(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
+ mContentTypeCombo->resetDirty();
+}
+
+bool LLPanelProfileClassified::getAutoRenew()
+{
+ return mAutoRenewEdit->getValue().asBoolean();
+}
+
+void LLPanelProfileClassified::sendUpdate()
+{
+ LLAvatarClassifiedInfo c_data;
+
+ if(getClassifiedId().isNull())
+ {
+ setClassifiedId(LLUUID::generateNewID());
+ }
+
+ c_data.agent_id = gAgent.getID();
+ c_data.classified_id = getClassifiedId();
+ // *HACK
+ // Categories on server start with 1 while combo-box index starts with 0
+ c_data.category = getCategory() + 1;
+ c_data.name = getClassifiedName();
+ c_data.description = getDescription();
+ c_data.parcel_id = getParcelId();
+ c_data.snapshot_id = getSnapshotId();
+ c_data.pos_global = getPosGlobal();
+ c_data.flags = getFlags();
+ c_data.price_for_listing = getPriceForListing();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
+
+ if(isNew())
+ {
+ // Lets assume there will be some error.
+ // Successful sendClassifiedInfoUpdate will trigger processProperties and
+ // let us know there was no error.
+ mIsNewWithErrors = true;
+ }
+}
+
+U32 LLPanelProfileClassified::getCategory()
+{
+ return mCategoryCombo->getCurrentIndex();
+}
+
+void LLPanelProfileClassified::setCategory(U32 category)
+{
+ mCategoryCombo->setCurrentByIndex(category);
+ mCategoryCombo->resetDirty();
+}
+
+U8 LLPanelProfileClassified::getFlags()
+{
+ bool auto_renew = mAutoRenewEdit->getValue().asBoolean();
+
+ bool mature = mContentTypeCombo->getCurrentIndex() == CB_ITEM_MATURE;
+
+ return pack_classified_flags_request(auto_renew, false, mature, false);
+}
+
+void LLPanelProfileClassified::enableSave(bool enable)
+{
+ mSaveButton->setEnabled(enable);
+}
+
+std::string LLPanelProfileClassified::makeClassifiedName()
+{
+ std::string name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ name = parcel->getName();
+ }
+
+ if(!name.empty())
+ {
+ return name;
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region)
+ {
+ name = region->getName();
+ }
+
+ return name;
+}
+
+void LLPanelProfileClassified::onSetLocationClick()
+{
+ setPosGlobal(gAgent.getPositionGlobal());
+ setParcelId(LLUUID::null);
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+
+ // mark classified as dirty
+ setValue(LLSD());
+
+ onChange();
+}
+
+void LLPanelProfileClassified::onChange()
+{
+ enableSave(isDirty());
+}
+
+void LLPanelProfileClassified::doSave()
+{
+ //*TODO: Fix all of this
+
+ mCanClose = true;
+ sendUpdate();
+ updateTabLabel(getClassifiedName());
+ resetDirty();
+
+ if (!canClose())
+ {
+ return;
+ }
+
+ if (!isNew() && !isNewWithErrors())
+ {
+ setEditMode(FALSE);
+ return;
+ }
+
+ updateButtons();
+}
+
+void LLPanelProfileClassified::onPublishFloaterPublishClicked()
+{
+ setPriceForListing(mPublishFloater->getPrice());
+
+ doSave();
+}
+
+std::string LLPanelProfileClassified::getLocationNotice()
+{
+ static std::string location_notice = getString("location_notice");
+ return location_notice;
+}
+
+bool LLPanelProfileClassified::isValidName()
+{
+ std::string name = getClassifiedName();
+ if (name.empty())
+ {
+ return false;
+ }
+ if (!isalnum(name[0]))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void LLPanelProfileClassified::notifyInvalidName()
+{
+ std::string name = getClassifiedName();
+ if (name.empty())
+ {
+ LLNotificationsUtil::add("BlankClassifiedName");
+ }
+ else if (!isalnum(name[0]))
+ {
+ LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
+ }
+}
+
+void LLPanelProfileClassified::onTexturePickerMouseEnter()
+{
+ mEditIcon->setVisible(TRUE);
+}
+
+void LLPanelProfileClassified::onTexturePickerMouseLeave()
+{
+ mEditIcon->setVisible(FALSE);
+}
+
+void LLPanelProfileClassified::onTextureSelected()
+{
+ setSnapshotId(mSnapshotCtrl->getValue().asUUID());
+ onChange();
+}
+
+void LLPanelProfileClassified::updateTabLabel(const std::string& title)
+{
+ setLabel(title);
+ LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
+ if (parent)
+ {
+ parent->setCurrentTabName(title);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPublishClassifiedFloater
+//-----------------------------------------------------------------------------
+
+LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
+{
+}
+
+BOOL LLPublishClassifiedFloater::postBuild()
+{
+ LLFloater::postBuild();
+
+ childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
+ childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
+
+ return TRUE;
+}
+
+void LLPublishClassifiedFloater::setPrice(S32 price)
+{
+ getChild<LLUICtrl>("price_for_listing")->setValue(price);
+}
+
+S32 LLPublishClassifiedFloater::getPrice()
+{
+ return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
+}
+
+void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
+{
+ getChild<LLButton>("publish_btn")->setClickedCallback(cb);
+}
+
+void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
+{
+ getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
+}
diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h
new file mode 100644
index 0000000000..912819e86b
--- /dev/null
+++ b/indra/newview/llpanelprofileclassifieds.h
@@ -0,0 +1,340 @@
+/**
+ * @file llpanelprofileclassifieds.h
+ * @brief LLPanelProfileClassifieds and related class implementations
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_PANELPROFILECLASSIFIEDS_H
+#define LL_PANELPROFILECLASSIFIEDS_H
+
+#include "llavatarpropertiesprocessor.h"
+#include "llclassifiedinfo.h"
+#include "llfloater.h"
+#include "llpanel.h"
+#include "llpanelavatar.h"
+#include "llrect.h"
+#include "lluuid.h"
+#include "v3dmath.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+
+class LLCheckBoxCtrl;
+class LLLineEditor;
+class LLMediaCtrl;
+class LLScrollContainer;
+class LLTabContainer;
+class LLTextEditor;
+class LLTextureCtrl;
+class LLUICtrl;
+
+
+class LLPublishClassifiedFloater : public LLFloater
+{
+public:
+ LLPublishClassifiedFloater(const LLSD& key);
+ virtual ~LLPublishClassifiedFloater();
+
+ BOOL postBuild() override;
+
+ void setPrice(S32 price);
+ S32 getPrice();
+
+ void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
+ void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
+};
+
+
+/**
+* Panel for displaying Avatar's picks.
+*/
+class LLPanelProfileClassifieds
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+ LLPanelProfileClassifieds();
+ /*virtual*/ ~LLPanelProfileClassifieds();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void selectClassified(const LLUUID& classified_id, bool edit);
+
+ void createClassified();
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+
+ void resetData() override;
+
+ void updateButtons();
+
+ void updateData() override;
+
+ bool hasNewClassifieds();
+ bool hasUnsavedChanges() override;
+ // commits changes to existing classifieds, but does not publish new classified!
+ void commitUnsavedChanges() override;
+
+private:
+ void onClickNewBtn();
+ void onClickDelete();
+ void callbackDeleteClassified(const LLSD& notification, const LLSD& response);
+
+ bool canAddNewClassified();
+ bool canDeleteClassified();
+
+ LLTabContainer* mTabContainer;
+ LLUICtrl* mNoItemsLabel;
+ LLButton* mNewButton;
+ LLButton* mDeleteButton;
+
+ LLUUID mClassifiedToSelectOnLoad;
+ bool mClassifiedEditOnLoad;
+ bool mSheduledClassifiedCreation;
+};
+
+
+class LLPanelProfileClassified
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+
+ static LLPanelProfileClassified* create();
+
+ LLPanelProfileClassified();
+
+ /*virtual*/ ~LLPanelProfileClassified();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+
+ void setSnapshotId(const LLUUID& id);
+
+ LLUUID getSnapshotId();
+
+ void setClassifiedId(const LLUUID& id) { mClassifiedId = id; }
+
+ LLUUID& getClassifiedId() { return mClassifiedId; }
+
+ void setClassifiedName(const std::string& name);
+
+ std::string getClassifiedName();
+
+ void setDescription(const std::string& desc);
+
+ std::string getDescription();
+
+ void setClassifiedLocation(const std::string& location);
+
+ std::string getClassifiedLocation();
+
+ void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+
+ LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ void setParcelId(const LLUUID& id) { mParcelId = id; }
+
+ LLUUID getParcelId() { return mParcelId; }
+
+ void setSimName(const std::string& sim_name) { mSimName = sim_name; }
+
+ std::string getSimName() { return mSimName; }
+
+ void setFromSearch(bool val) { mFromSearch = val; }
+
+ bool fromSearch() { return mFromSearch; }
+
+ bool getInfoLoaded() { return mInfoLoaded; }
+
+ void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; }
+
+ BOOL isDirty() const override;
+
+ void resetDirty() override;
+
+ bool isNew() { return mIsNew; }
+
+ bool isNewWithErrors() { return mIsNewWithErrors; }
+
+ bool canClose();
+
+ U32 getCategory();
+
+ void setCategory(U32 category);
+
+ U32 getContentType();
+
+ void setContentType(bool mature);
+
+ bool getAutoRenew();
+
+ S32 getPriceForListing() { return mPriceForListing; }
+
+ void setEditMode(BOOL edit_mode);
+ bool getEditMode() {return mEditMode;}
+
+ static void setClickThrough(
+ const LLUUID& classified_id,
+ S32 teleport,
+ S32 map,
+ S32 profile,
+ bool from_new_table);
+
+ static void sendClickMessage(
+ const std::string& type,
+ bool from_search,
+ const LLUUID& classified_id,
+ const LLUUID& parcel_id,
+ const LLVector3d& global_pos,
+ const std::string& sim_name);
+
+ void doSave();
+
+protected:
+
+ void resetData() override;
+
+ void resetControls();
+
+ void updateButtons();
+ void updateInfoRect();
+
+ static std::string createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ void sendClickMessage(const std::string& type);
+
+ void scrollToTop();
+
+ void onEditClick();
+ void onCancelClick();
+ void onSaveClick();
+ void onMapClick();
+ void onTeleportClick();
+
+ void sendUpdate();
+
+ void enableSave(bool enable);
+
+ void enableEditing(bool enable);
+
+ std::string makeClassifiedName();
+
+ void setPriceForListing(S32 price) { mPriceForListing = price; }
+
+ U8 getFlags();
+
+ std::string getLocationNotice();
+
+ bool isValidName();
+
+ void notifyInvalidName();
+
+ void onSetLocationClick();
+ void onChange();
+
+ void onPublishFloaterPublishClicked();
+
+ void onTexturePickerMouseEnter();
+ void onTexturePickerMouseLeave();
+
+ void onTextureSelected();
+
+ void updateTabLabel(const std::string& title);
+
+private:
+
+ LLTextureCtrl* mSnapshotCtrl;
+ LLUICtrl* mEditIcon;
+ LLUICtrl* mClassifiedNameText;
+ LLTextEditor* mClassifiedDescText;
+ LLLineEditor* mClassifiedNameEdit;
+ LLTextEditor* mClassifiedDescEdit;
+ LLUICtrl* mLocationText;
+ LLUICtrl* mLocationEdit;
+ LLUICtrl* mCategoryText;
+ LLComboBox* mCategoryCombo;
+ LLUICtrl* mContentTypeText;
+ LLIconCtrl* mContentTypeM;
+ LLIconCtrl* mContentTypeG;
+ LLComboBox* mContentTypeCombo;
+ LLUICtrl* mPriceText;
+ LLUICtrl* mAutoRenewText;
+ LLUICtrl* mAutoRenewEdit;
+
+ LLButton* mMapButton;
+ LLButton* mTeleportButton;
+ LLButton* mEditButton;
+ LLButton* mSaveButton;
+ LLButton* mSetLocationButton;
+ LLButton* mCancelButton;
+
+ LLPanel* mUtilityBtnCnt;
+ LLPanel* mPublishBtnsCnt;
+ LLPanel* mSaveBtnCnt;
+ LLPanel* mCancelBtnCnt;
+
+ LLScrollContainer* mScrollContainer;
+ LLView* mInfoPanel;
+ LLPanel* mInfoScroll;
+ LLPanel* mEditPanel;
+
+
+ LLUUID mClassifiedId;
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ std::string mSimName;
+ bool mFromSearch;
+ bool mInfoLoaded;
+ bool mEditMode;
+
+ // Needed for stat tracking
+ S32 mTeleportClicksOld;
+ S32 mMapClicksOld;
+ S32 mProfileClicksOld;
+ S32 mTeleportClicksNew;
+ S32 mMapClicksNew;
+ S32 mProfileClicksNew;
+
+ S32 mPriceForListing;
+
+ static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
+
+ typedef std::list<LLPanelProfileClassified*> panel_list_t;
+ static panel_list_t sAllPanels;
+
+
+ bool mIsNew;
+ bool mIsNewWithErrors;
+ bool mCanClose;
+ bool mEditOnLoad;
+
+ LLPublishClassifiedFloater* mPublishFloater;
+};
+
+#endif // LL_PANELPROFILECLASSIFIEDS_H
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
new file mode 100644
index 0000000000..774119f169
--- /dev/null
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -0,0 +1,883 @@
+/**
+ * @file llpanelprofilepicks.cpp
+ * @brief LLPanelProfilePicks and related class implementations
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelprofilepicks.h"
+
+#include "llagent.h"
+#include "llagentpicksinfo.h"
+#include "llavataractions.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llcommandhandler.h"
+#include "lldispatcher.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+#include "llparcel.h"
+#include "llstartup.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+static LLPanelInjector<LLPanelProfilePicks> t_panel_profile_picks("panel_profile_picks");
+static LLPanelInjector<LLPanelProfilePick> t_panel_profile_pick("panel_profile_pick");
+
+
+class LLPickHandler : public LLCommandHandler
+{
+public:
+
+ // requires trusted browser to trigger
+ LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
+
+ bool handle(const LLSD& params, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
+ if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
+ {
+ LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
+ // handle app/pick/create urls first
+ if (params.size() == 1 && params[0].asString() == "create")
+ {
+ LLAvatarActions::createPick();
+ return true;
+ }
+
+ // then handle the general app/pick/{UUID}/{CMD} urls
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the pick_id
+ LLUUID pick_id;
+ if (!pick_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // edit the pick in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "edit")
+ {
+ LLAvatarActions::showPick(gAgent.getID(), pick_id);
+ return true;
+ }
+ else
+ {
+ LL_WARNS() << "unknown verb " << verb << LL_ENDL;
+ return false;
+ }
+ }
+};
+LLPickHandler gPickHandler;
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfilePicks
+//-----------------------------------------------------------------------------
+
+LLPanelProfilePicks::LLPanelProfilePicks()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mPickToSelectOnLoad(LLUUID::null)
+{
+}
+
+LLPanelProfilePicks::~LLPanelProfilePicks()
+{
+}
+
+void LLPanelProfilePicks::onOpen(const LLSD& key)
+{
+ LLPanelProfilePropertiesProcessorTab::onOpen(key);
+
+ resetData();
+
+ bool own_profile = getSelfProfile();
+ if (own_profile)
+ {
+ mNewButton->setVisible(TRUE);
+ mNewButton->setEnabled(FALSE);
+
+ mDeleteButton->setVisible(TRUE);
+ mDeleteButton->setEnabled(FALSE);
+ }
+
+ childSetVisible("buttons_header", own_profile);
+}
+
+void LLPanelProfilePicks::createPick(const LLPickData &data)
+{
+ if (getIsLoaded())
+ {
+ if (canAddNewPick())
+ {
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ pick_panel->processProperties(&data);
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(true).
+ label(pick_panel->getPickName()));
+ updateButtons();
+ }
+ else
+ {
+ // This means that something doesn't properly check limits
+ // before creating a pick
+ LL_WARNS() << "failed to add pick" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mSheduledPickCreation.push_back(data);
+ }
+}
+
+void LLPanelProfilePicks::selectPick(const LLUUID& pick_id)
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ if (pick_panel->getPickId() == pick_id)
+ {
+ mTabContainer->selectTabPanel(pick_panel);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ mPickToSelectOnLoad = pick_id;
+ }
+}
+
+BOOL LLPanelProfilePicks::postBuild()
+{
+ mTabContainer = getChild<LLTabContainer>("tab_picks");
+ mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
+ mNewButton = getChild<LLButton>("new_btn");
+ mDeleteButton = getChild<LLButton>("delete_btn");
+
+ mNewButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickNewBtn, this));
+ mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickDelete, this));
+
+ return TRUE;
+}
+
+void LLPanelProfilePicks::onClickNewBtn()
+{
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(true).
+ label(pick_panel->getPickName()));
+ updateButtons();
+}
+
+void LLPanelProfilePicks::onClickDelete()
+{
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
+ if (pick_panel)
+ {
+ LLUUID pick_id = pick_panel->getPickId();
+ LLSD args;
+ args["PICK"] = pick_panel->getPickName();
+ LLSD payload;
+ payload["pick_id"] = pick_id;
+ payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
+ LLNotificationsUtil::add("ProfileDeletePick", args, payload,
+ boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2));
+ }
+}
+
+void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ LLUUID pick_id = notification["payload"]["pick_id"].asUUID();
+ S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
+
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel && pick_panel->getPickId() == pick_id)
+ {
+ mTabContainer->removeTabPanel(pick_panel);
+ }
+
+ if (pick_id.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendPickDelete(pick_id);
+ }
+
+ updateButtons();
+ }
+}
+
+void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PICKS == type)
+ {
+ LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
+ if (avatar_picks && getAvatarId() == avatar_picks->target_id)
+ {
+ processProperties(avatar_picks);
+ }
+ }
+}
+
+void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks)
+{
+ LLUUID selected_id = mPickToSelectOnLoad;
+ bool has_selection = false;
+ if (mPickToSelectOnLoad.isNull())
+ {
+ if (mTabContainer->getTabCount() > 0)
+ {
+ LLPanelProfilePick* active_pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
+ if (active_pick_panel)
+ {
+ selected_id = active_pick_panel->getPickId();
+ }
+ }
+ }
+
+ mTabContainer->deleteAllTabs();
+
+ LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
+ for (; avatar_picks->picks_list.end() != it; ++it)
+ {
+ LLUUID pick_id = it->first;
+ std::string pick_name = it->second;
+
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+
+ pick_panel->setPickId(pick_id);
+ pick_panel->setPickName(pick_name);
+ pick_panel->setAvatarId(getAvatarId());
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(selected_id == pick_id).
+ label(pick_name));
+
+ if (selected_id == pick_id)
+ {
+ has_selection = true;
+ }
+ }
+
+ while (!mSheduledPickCreation.empty() && canAddNewPick())
+ {
+ const LLPickData data =
+ mSheduledPickCreation.back();
+
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ pick_panel->processProperties(&data);
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(!has_selection).
+ label(pick_panel->getPickName()));
+
+ mSheduledPickCreation.pop_back();
+ has_selection = true;
+ }
+
+ // reset 'do on load' values
+ mPickToSelectOnLoad = LLUUID::null;
+ mSheduledPickCreation.clear();
+
+ if (getSelfProfile())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoPicksText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksText"));
+ }
+
+ bool has_data = mTabContainer->getTabCount() > 0;
+ mNoItemsLabel->setVisible(!has_data);
+ if (has_data && !has_selection)
+ {
+ mTabContainer->selectFirstTab();
+ }
+
+ setLoaded();
+ updateButtons();
+}
+
+void LLPanelProfilePicks::resetData()
+{
+ resetLoading();
+ mTabContainer->deleteAllTabs();
+}
+
+void LLPanelProfilePicks::updateButtons()
+{
+ if (getSelfProfile())
+ {
+ mNewButton->setEnabled(canAddNewPick());
+ mDeleteButton->setEnabled(canDeletePick());
+ }
+}
+
+void LLPanelProfilePicks::apply()
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ pick_panel->apply();
+ }
+ }
+ }
+}
+
+void LLPanelProfilePicks::updateData()
+{
+ // Send picks request only once
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id);
+ }
+ if (!getIsLoaded())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+ mNoItemsLabel->setVisible(TRUE);
+ }
+}
+
+bool LLPanelProfilePicks::hasUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel && (pick_panel->isDirty() || pick_panel->isDirty()))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLPanelProfilePicks::commitUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ pick_panel->apply();
+ }
+ }
+}
+
+bool LLPanelProfilePicks::canAddNewPick()
+{
+ return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() &&
+ mTabContainer->getTabCount() < LLAgentPicksInfo::getInstance()->getMaxNumberOfPicks());
+}
+
+bool LLPanelProfilePicks::canDeletePick()
+{
+ return (mTabContainer->getTabCount() > 0);
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfilePick
+//-----------------------------------------------------------------------------
+
+LLPanelProfilePick::LLPanelProfilePick()
+ : LLPanelProfilePropertiesProcessorTab()
+ , LLRemoteParcelInfoObserver()
+ , mSnapshotCtrl(NULL)
+ , mPickId(LLUUID::null)
+ , mParcelId(LLUUID::null)
+ , mRequestedId(LLUUID::null)
+ , mLocationChanged(false)
+ , mNewPick(false)
+ , mIsEditing(false)
+{
+}
+
+//static
+LLPanelProfilePick* LLPanelProfilePick::create()
+{
+ LLPanelProfilePick* panel = new LLPanelProfilePick();
+ panel->buildFromFile("panel_profile_pick.xml");
+ return panel;
+}
+
+LLPanelProfilePick::~LLPanelProfilePick()
+{
+ if (mParcelId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+ }
+}
+
+void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
+
+ // creating new Pick
+ if (getPickId().isNull() && getSelfProfile())
+ {
+ mNewPick = true;
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
+ std::string pick_name, pick_desc, region_name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ parcel_id = parcel->getID();
+ pick_name = parcel->getName();
+ pick_desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setParcelID(parcel_id);
+ setPickName(pick_name.empty() ? region_name : pick_name);
+ setPickDesc(pick_desc);
+ setSnapshotId(snapshot_id);
+ setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
+
+ enableSaveButton(TRUE);
+ }
+ else
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
+
+ enableSaveButton(FALSE);
+ }
+
+ resetDirty();
+
+ if (getSelfProfile())
+ {
+ mPickName->setEnabled(TRUE);
+ mPickDescription->setEnabled(TRUE);
+ mSetCurrentLocationButton->setVisible(TRUE);
+ }
+ else
+ {
+ mSnapshotCtrl->setEnabled(FALSE);
+ }
+}
+
+BOOL LLPanelProfilePick::postBuild()
+{
+ mPickName = getChild<LLLineEditor>("pick_name");
+ mPickDescription = getChild<LLTextEditor>("pick_desc");
+ mSaveButton = getChild<LLButton>("save_changes_btn");
+ mCreateButton = getChild<LLButton>("create_changes_btn");
+ mCancelButton = getChild<LLButton>("cancel_changes_btn");
+ mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn");
+
+ mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot");
+ mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this));
+
+ childSetAction("teleport_btn", boost::bind(&LLPanelProfilePick::onClickTeleport, this));
+ childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePick::onClickMap, this));
+
+ mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
+ mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
+ mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this));
+ mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this));
+
+ mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL);
+ mPickName->setEnabled(FALSE);
+
+ mPickDescription->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1));
+ mPickDescription->setFocusReceivedCallback(boost::bind(&LLPanelProfilePick::onDescriptionFocusReceived, this));
+
+ getChild<LLUICtrl>("pick_location")->setEnabled(FALSE);
+
+ return TRUE;
+}
+
+void LLPanelProfilePick::onDescriptionFocusReceived()
+{
+ if (!mIsEditing && getSelfProfile())
+ {
+ mIsEditing = true;
+ mPickDescription->setParseHTML(false);
+ }
+}
+
+void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PICK_INFO != type)
+ {
+ return;
+ }
+
+ LLPickData* pick_info = static_cast<LLPickData*>(data);
+ if (!pick_info
+ || pick_info->creator_id != getAvatarId()
+ || pick_info->pick_id != getPickId())
+ {
+ return;
+ }
+
+ processProperties(pick_info);
+}
+
+void LLPanelProfilePick::processProperties(const LLPickData* pick_info)
+{
+ mIsEditing = false;
+ mPickDescription->setParseHTML(true);
+ mParcelId = pick_info->parcel_id;
+ setSnapshotId(pick_info->snapshot_id);
+ if (!getSelfProfile())
+ {
+ mSnapshotCtrl->setEnabled(FALSE);
+ }
+ setPickName(pick_info->name);
+ setPickDesc(pick_info->desc);
+ setPosGlobal(pick_info->pos_global);
+
+ // Send remote parcel info request to get parcel name and sim (region) name.
+ sendParcelInfoRequest();
+
+ // *NOTE dzaporozhan
+ // We want to keep listening to APT_PICK_INFO because user may
+ // edit the Pick and we have to update Pick info panel.
+ // revomeObserver is called from onClickBack
+
+ setLoaded();
+}
+
+void LLPanelProfilePick::apply()
+{
+ if ((mNewPick || getIsLoaded()) && isDirty())
+ {
+ sendUpdate();
+ }
+}
+
+void LLPanelProfilePick::setSnapshotId(const LLUUID& id)
+{
+ mSnapshotCtrl->setImageAssetID(id);
+ mSnapshotCtrl->setValid(TRUE);
+}
+
+void LLPanelProfilePick::setPickName(const std::string& name)
+{
+ mPickName->setValue(name);
+}
+
+const std::string LLPanelProfilePick::getPickName()
+{
+ return mPickName->getValue().asString();
+}
+
+void LLPanelProfilePick::setPickDesc(const std::string& desc)
+{
+ mPickDescription->setValue(desc);
+}
+
+void LLPanelProfilePick::setPickLocation(const std::string& location)
+{
+ getChild<LLUICtrl>("pick_location")->setValue(location);
+}
+
+void LLPanelProfilePick::onClickMap()
+{
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfilePick::onClickTeleport()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+void LLPanelProfilePick::enableSaveButton(BOOL enable)
+{
+ childSetVisible("save_changes_lp", enable);
+
+ childSetVisible("save_btn_lp", enable && !mNewPick);
+ childSetVisible("create_btn_lp", enable && mNewPick);
+ childSetVisible("cancel_btn_lp", enable && !mNewPick);
+}
+
+void LLPanelProfilePick::onSnapshotChanged()
+{
+ enableSaveButton(TRUE);
+}
+
+void LLPanelProfilePick::onPickChanged(LLUICtrl* ctrl)
+{
+ if (ctrl && ctrl == mPickName)
+ {
+ updateTabLabel(mPickName->getText());
+ }
+
+ enableSaveButton(isDirty());
+}
+
+void LLPanelProfilePick::resetDirty()
+{
+ LLPanel::resetDirty();
+
+ mPickName->resetDirty();
+ mPickDescription->resetDirty();
+ mSnapshotCtrl->resetDirty();
+ mLocationChanged = false;
+}
+
+BOOL LLPanelProfilePick::isDirty() const
+{
+ if (mNewPick
+ || LLPanel::isDirty()
+ || mLocationChanged
+ || mSnapshotCtrl->isDirty()
+ || mPickName->isDirty()
+ || mPickDescription->isDirty())
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void LLPanelProfilePick::onClickSetLocation()
+{
+ // Save location for later use.
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ std::string parcel_name, region_name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ mParcelId = parcel->getID();
+ parcel_name = parcel->getName();
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
+
+ mLocationChanged = true;
+ enableSaveButton(TRUE);
+}
+
+void LLPanelProfilePick::onClickSave()
+{
+ sendUpdate();
+
+ mLocationChanged = false;
+}
+
+void LLPanelProfilePick::onClickCancel()
+{
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
+ mLocationChanged = false;
+ enableSaveButton(FALSE);
+}
+
+std::string LLPanelProfilePick::getLocationNotice()
+{
+ static const std::string notice = getString("location_notice");
+ return notice;
+}
+
+void LLPanelProfilePick::sendParcelInfoRequest()
+{
+ if (mParcelId != mRequestedId)
+ {
+ if (mRequestedId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this);
+ }
+ LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
+ LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
+
+ mRequestedId = mParcelId;
+ }
+}
+
+void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data)
+{
+ setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name, parcel_data.sim_name, getPosGlobal()));
+
+ // We have received parcel info for the requested ID so clear it now.
+ mRequestedId.setNull();
+
+ if (mParcelId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+ }
+}
+
+void LLPanelProfilePick::sendUpdate()
+{
+ LLPickData pick_data;
+
+ // If we don't have a pick id yet, we'll need to generate one,
+ // otherwise we'll keep overwriting pick_id 00000 in the database.
+ if (getPickId().isNull())
+ {
+ getPickId().generate();
+ }
+
+ pick_data.agent_id = gAgentID;
+ pick_data.session_id = gAgent.getSessionID();
+ pick_data.pick_id = getPickId();
+ pick_data.creator_id = gAgentID;;
+
+ //legacy var need to be deleted
+ pick_data.top_pick = FALSE;
+ pick_data.parcel_id = mParcelId;
+ pick_data.name = getPickName();
+ pick_data.desc = mPickDescription->getValue().asString();
+ pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
+ pick_data.pos_global = getPosGlobal();
+ pick_data.sort_order = 0;
+ pick_data.enabled = TRUE;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoUpdate(&pick_data);
+
+ if(mNewPick)
+ {
+ // Assume a successful create pick operation, make new number of picks
+ // available immediately. Actual number of picks will be requested in
+ // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
+ LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
+ }
+}
+
+// static
+std::string LLPanelProfilePick::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
+{
+ std::string location_text(owner_name);
+ if (!original_name.empty())
+ {
+ if (!location_text.empty())
+ {
+ location_text.append(", ");
+ }
+ location_text.append(original_name);
+
+ }
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ {
+ location_text.append(", ");
+ }
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ {
+ location_text.append(" ");
+ }
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+ return location_text;
+}
+
+void LLPanelProfilePick::updateTabLabel(const std::string& title)
+{
+ setLabel(title);
+ LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
+ if (parent)
+ {
+ parent->setCurrentTabName(title);
+ }
+}
+
diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h
new file mode 100644
index 0000000000..f84463cc9b
--- /dev/null
+++ b/indra/newview/llpanelprofilepicks.h
@@ -0,0 +1,248 @@
+/**
+ * @file llpanelprofilepicks.h
+ * @brief LLPanelProfilePicks and related class definitions
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPICKS_H
+#define LL_LLPANELPICKS_H
+
+#include "llpanel.h"
+#include "lluuid.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llpanelavatar.h"
+#include "llremoteparcelrequest.h"
+
+class LLTabContainer;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLLineEditor;
+class LLTextEditor;
+
+
+/**
+* Panel for displaying Avatar's picks.
+*/
+class LLPanelProfilePicks
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+ LLPanelProfilePicks();
+ /*virtual*/ ~LLPanelProfilePicks();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void createPick(const LLPickData &data);
+ void selectPick(const LLUUID& pick_id);
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLAvatarPicks* avatar_picks);
+
+ void resetData() override;
+
+ void updateButtons();
+
+ /**
+ * Saves changes.
+ */
+ virtual void apply();
+
+ /**
+ * Sends update data request to server.
+ */
+ void updateData() override;
+
+ bool hasUnsavedChanges() override;
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+private:
+ void onClickNewBtn();
+ void onClickDelete();
+ void callbackDeletePick(const LLSD& notification, const LLSD& response);
+
+ bool canAddNewPick();
+ bool canDeletePick();
+
+ LLTabContainer* mTabContainer;
+ LLUICtrl* mNoItemsLabel;
+ LLButton* mNewButton;
+ LLButton* mDeleteButton;
+
+ LLUUID mPickToSelectOnLoad;
+ std::list<LLPickData> mSheduledPickCreation;
+};
+
+
+class LLPanelProfilePick
+ : public LLPanelProfilePropertiesProcessorTab
+ , public LLRemoteParcelInfoObserver
+{
+public:
+
+ // Creates new panel
+ static LLPanelProfilePick* create();
+
+ LLPanelProfilePick();
+
+ /*virtual*/ ~LLPanelProfilePick();
+
+ BOOL postBuild() override;
+
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ void setPickId(const LLUUID& id) { mPickId = id; }
+ virtual LLUUID& getPickId() { return mPickId; }
+
+ virtual void setPickName(const std::string& name);
+ const std::string getPickName();
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLPickData* pick_data);
+
+ /**
+ * Returns true if any of Pick properties was changed by user.
+ */
+ BOOL isDirty() const override;
+
+ /**
+ * Saves changes.
+ */
+ virtual void apply();
+
+ void updateTabLabel(const std::string& title);
+
+ //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
+ void processParcelInfo(const LLParcelData& parcel_data) override;
+ void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; }
+ void setErrorStatus(S32 status, const std::string& reason) override {};
+
+protected:
+
+ /**
+ * Sends remote parcel info request to resolve parcel name from its ID.
+ */
+ void sendParcelInfoRequest();
+
+ /**
+ * "Location text" is actually the owner name, the original
+ * name that owner gave the parcel, and the location.
+ */
+ static std::string createLocationText(
+ const std::string& owner_name,
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ /**
+ * Sets snapshot id.
+ *
+ * Will mark snapshot control as valid if id is not null.
+ * Will mark snapshot control as invalid if id is null. If null id is a valid value,
+ * you have to manually mark snapshot is valid.
+ */
+ virtual void setSnapshotId(const LLUUID& id);
+ virtual void setPickDesc(const std::string& desc);
+ virtual void setPickLocation(const std::string& location);
+
+ virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+ virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ /**
+ * Callback for "Map" button, opens Map
+ */
+ void onClickMap();
+
+ /**
+ * Callback for "Teleport" button, teleports user to Pick location.
+ */
+ void onClickTeleport();
+
+ /**
+ * Enables/disables "Save" button
+ */
+ void enableSaveButton(BOOL enable);
+
+ /**
+ * Called when snapshot image changes.
+ */
+ void onSnapshotChanged();
+
+ /**
+ * Callback for Pick snapshot, name and description changed event.
+ */
+ void onPickChanged(LLUICtrl* ctrl);
+
+ /**
+ * Resets panel and all cantrols to unedited state
+ */
+ void resetDirty() override;
+
+ /**
+ * Callback for "Set Location" button click
+ */
+ void onClickSetLocation();
+
+ /**
+ * Callback for "Save" and "Create" button click
+ */
+ void onClickSave();
+
+ /**
+ * Callback for "Save" button click
+ */
+ void onClickCancel();
+
+ std::string getLocationNotice();
+
+ /**
+ * Sends Pick properties to server.
+ */
+ void sendUpdate();
+
+protected:
+
+ LLTextureCtrl* mSnapshotCtrl;
+ LLLineEditor* mPickName;
+ LLTextEditor* mPickDescription;
+ LLButton* mSetCurrentLocationButton;
+ LLButton* mSaveButton;
+ LLButton* mCreateButton;
+ LLButton* mCancelButton;
+
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ LLUUID mPickId;
+ LLUUID mRequestedId;
+
+ bool mLocationChanged;
+ bool mNewPick;
+ bool mIsEditing;
+
+ void onDescriptionFocusReceived();
+};
+
+#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 89c558e4f8..db37938448 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -51,6 +51,7 @@
#include "llfocusmgr.h"
#include "llmanipscale.h"
#include "llinventorymodel.h"
+#include "llmenubutton.h"
#include "llpreviewscript.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -145,6 +146,15 @@ BOOL LLPanelVolume::postBuild()
getChild<LLUICtrl>("Light Ambiance")->setValidateBeforeCommit( precommitValidate);
}
+ // REFLECTION PROBE Parameters
+ {
+ childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this);
+ childSetCommitCallback("Probe Dynamic", onCommitProbe, this);
+ childSetCommitCallback("Probe Volume Type", onCommitProbe, this);
+ childSetCommitCallback("Probe Ambiance", onCommitProbe, this);
+ childSetCommitCallback("Probe Near Clip", onCommitProbe, this);
+ }
+
// PHYSICS Parameters
{
// PhysicsShapeType combobox
@@ -168,6 +178,9 @@ BOOL LLPanelVolume::postBuild()
mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution));
}
+ mMenuClipboardFeatures = getChild<LLMenuButton>("clipboard_features_params_btn");
+ mMenuClipboardLight = getChild<LLMenuButton>("clipboard_light_params_btn");
+
std::map<std::string, std::string> material_name_map;
material_name_map["Stone"]= LLTrans::getString("Stone");
material_name_map["Metal"]= LLTrans::getString("Metal");
@@ -208,6 +221,8 @@ LLPanelVolume::LLPanelVolume()
{
setMouseOpaque(FALSE);
+ mCommitCallbackRegistrar.add("PanelVolume.menuDoToSelected", boost::bind(&LLPanelVolume::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelVolume.menuEnable", boost::bind(&LLPanelVolume::menuEnableItem, this, _2));
}
@@ -360,6 +375,43 @@ void LLPanelVolume::getState( )
getChildView("Light Ambiance")->setEnabled(false);
}
+ // Reflection Probe
+ BOOL is_probe = volobjp && volobjp->isReflectionProbe();
+ getChild<LLUICtrl>("Reflection Probe")->setValue(is_probe);
+ getChildView("Reflection Probe")->setEnabled(editable && single_volume && volobjp);
+
+ bool probe_enabled = is_probe && editable && single_volume;
+
+ getChildView("Probe Dynamic")->setEnabled(probe_enabled);
+ getChildView("Probe Volume Type")->setEnabled(probe_enabled);
+ getChildView("Probe Ambiance")->setEnabled(probe_enabled);
+ getChildView("Probe Near Clip")->setEnabled(probe_enabled);
+
+ if (!probe_enabled)
+ {
+ getChild<LLComboBox>("Probe Volume Type", true)->clear();
+ getChild<LLSpinCtrl>("Probe Ambiance", true)->clear();
+ getChild<LLSpinCtrl>("Probe Near Clip", true)->clear();
+ getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->clear();
+ }
+ else
+ {
+ std::string volume_type;
+ if (volobjp->getReflectionProbeIsBox())
+ {
+ volume_type = "Box";
+ }
+ else
+ {
+ volume_type = "Sphere";
+ }
+
+ getChild<LLComboBox>("Probe Volume Type", true)->setValue(volume_type);
+ getChild<LLSpinCtrl>("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance());
+ getChild<LLSpinCtrl>("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip());
+ getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->setValue(volobjp->getReflectionProbeIsDynamic());
+ }
+
// Animated Mesh
BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject();
getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh);
@@ -409,7 +461,6 @@ void LLPanelVolume::getState( )
gAgentAvatarp->updateMeshVisibility();
}
}
-
// Flexible properties
BOOL is_flexible = volobjp && volobjp->isFlexible();
@@ -564,6 +615,9 @@ void LLPanelVolume::getState( )
mObject = objectp;
mRootObject = root_objectp;
+
+ mMenuClipboardFeatures->setEnabled(editable && single_volume && volobjp); // Note: physics doesn't need to be limited by single volume
+ mMenuClipboardLight->setEnabled(editable && single_volume && volobjp);
}
// static
@@ -587,13 +641,6 @@ void LLPanelVolume::refresh()
mRootObject = NULL;
}
- BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE;
-
- getChildView("Light FOV")->setVisible( visible);
- getChildView("Light Focus")->setVisible( visible);
- getChildView("Light Ambiance")->setVisible( visible);
- getChildView("light texture control")->setVisible( visible);
-
bool enable_mesh = false;
LLSD sim_features;
@@ -647,6 +694,11 @@ void LLPanelVolume::clearCtrls()
getChildView("Light Radius")->setEnabled(false);
getChildView("Light Falloff")->setEnabled(false);
+ getChildView("Reflection Probe")->setEnabled(false);;
+ getChildView("Probe Volume Type")->setEnabled(false);
+ getChildView("Probe Dynamic")->setEnabled(false);
+ getChildView("Probe Ambiance")->setEnabled(false);
+ getChildView("Probe Near Clip")->setEnabled(false);
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
getChildView("FlexNumSections")->setEnabled(false);
@@ -684,6 +736,20 @@ void LLPanelVolume::sendIsLight()
LL_INFOS() << "update light sent" << LL_ENDL;
}
+void LLPanelVolume::sendIsReflectionProbe()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+ BOOL value = getChild<LLUICtrl>("Reflection Probe")->getValue();
+ volobjp->setIsReflectionProbe(value);
+ LL_INFOS() << "update reflection probe sent" << LL_ENDL;
+}
+
void LLPanelVolume::sendIsFlexible()
{
LLViewerObject* objectp = mObject;
@@ -831,6 +897,311 @@ void LLPanelVolume::onLightSelectTexture(const LLSD& data)
}
}
+void LLPanelVolume::onCopyFeatures()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ LLSD clipboard;
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Flexi Prim
+ if (volobjp && volobjp->isFlexible())
+ {
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ clipboard["flex"]["lod"] = attributes->getSimulateLOD();
+ clipboard["flex"]["gav"] = attributes->getGravity();
+ clipboard["flex"]["ten"] = attributes->getTension();
+ clipboard["flex"]["fri"] = attributes->getAirFriction();
+ clipboard["flex"]["sen"] = attributes->getWindSensitivity();
+ LLVector3 force = attributes->getUserForce();
+ clipboard["flex"]["forx"] = force.mV[0];
+ clipboard["flex"]["fory"] = force.mV[1];
+ clipboard["flex"]["forz"] = force.mV[2];
+ }
+ }
+
+ // Physics
+ {
+ clipboard["physics"]["shape"] = objectp->getPhysicsShapeType();
+ clipboard["physics"]["gravity"] = objectp->getPhysicsGravity();
+ clipboard["physics"]["friction"] = objectp->getPhysicsFriction();
+ clipboard["physics"]["density"] = objectp->getPhysicsDensity();
+ clipboard["physics"]["restitution"] = objectp->getPhysicsRestitution();
+
+ U8 material_code = 0;
+ struct f : public LLSelectedTEGetFunctor<U8>
+ {
+ U8 get(LLViewerObject* object, S32 te)
+ {
+ return object->getMaterial();
+ }
+ } func;
+ bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, material_code);
+ // This should always be true since material should be per object.
+ if (material_same)
+ {
+ clipboard["physics"]["material"] = material_code;
+ }
+ }
+
+ mClipboardParams["features"] = clipboard;
+}
+
+void LLPanelVolume::onPasteFeatures()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp && mClipboardParams.has("features"))
+ {
+ return;
+ }
+
+ LLSD &clipboard = mClipboardParams["features"];
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Physics
+ bool is_root = objectp->isRoot();
+
+ // Not sure if phantom should go under physics, but doesn't fit elsewhere
+ BOOL is_phantom = clipboard["is_phantom"].asBoolean() && is_root;
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(is_phantom);
+
+ BOOL is_physical = clipboard["is_physical"].asBoolean() && is_root;
+ LLSelectMgr::getInstance()->selectionUpdatePhysics(is_physical);
+
+ if (clipboard.has("physics"))
+ {
+ objectp->setPhysicsShapeType((U8)clipboard["physics"]["shape"].asInteger());
+ U8 cur_material = objectp->getMaterial();
+ U8 material = (U8)clipboard["physics"]["material"].asInteger() | (cur_material & ~LL_MCODE_MASK);
+
+ objectp->setMaterial(material);
+ objectp->sendMaterialUpdate();
+ objectp->setPhysicsGravity(clipboard["physics"]["gravity"].asReal());
+ objectp->setPhysicsFriction(clipboard["physics"]["friction"].asReal());
+ objectp->setPhysicsDensity(clipboard["physics"]["density"].asReal());
+ objectp->setPhysicsRestitution(clipboard["physics"]["restitution"].asReal());
+ objectp->updateFlags(TRUE);
+ }
+
+ // Flexible
+ bool is_flexible = clipboard.has("flex");
+ if (is_flexible && volobjp->canBeFlexible())
+ {
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ BOOL update_shape = FALSE;
+
+ // do before setParameterEntry or it will think that it is already flexi
+ update_shape = volobjp->setIsFlexible(is_flexible);
+
+ if (objectp->getClickAction() == CLICK_ACTION_SIT)
+ {
+ objectp->setClickAction(CLICK_ACTION_NONE);
+ }
+
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ LLFlexibleObjectData new_attributes;
+ new_attributes = *attributes;
+ new_attributes.setSimulateLOD(clipboard["flex"]["lod"].asInteger());
+ new_attributes.setGravity(clipboard["flex"]["gav"].asReal());
+ new_attributes.setTension(clipboard["flex"]["ten"].asReal());
+ new_attributes.setAirFriction(clipboard["flex"]["fri"].asReal());
+ new_attributes.setWindSensitivity(clipboard["flex"]["sen"].asReal());
+ F32 fx = (F32)clipboard["flex"]["forx"].asReal();
+ F32 fy = (F32)clipboard["flex"]["fory"].asReal();
+ F32 fz = (F32)clipboard["flex"]["forz"].asReal();
+ LLVector3 force(fx, fy, fz);
+ new_attributes.setUserForce(force);
+ objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true);
+ }
+
+ if (update_shape)
+ {
+ mObject->sendShapeUpdate();
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom());
+ }
+ }
+ else
+ {
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ if (volobjp->setIsFlexible(false))
+ {
+ mObject->sendShapeUpdate();
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom());
+ }
+ }
+}
+
+void LLPanelVolume::onCopyLight()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ LLSD clipboard;
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Light Source
+ if (volobjp && volobjp->getIsLight())
+ {
+ clipboard["light"]["intensity"] = volobjp->getLightIntensity();
+ clipboard["light"]["radius"] = volobjp->getLightRadius();
+ clipboard["light"]["falloff"] = volobjp->getLightFalloff();
+ LLColor3 color = volobjp->getLightSRGBColor();
+ clipboard["light"]["r"] = color.mV[0];
+ clipboard["light"]["g"] = color.mV[1];
+ clipboard["light"]["b"] = color.mV[2];
+
+ // Spotlight
+ if (volobjp->isLightSpotlight())
+ {
+ LLUUID id = volobjp->getLightTextureID();
+ if (id.notNull() && get_can_copy_texture(id))
+ {
+ clipboard["spot"]["id"] = id;
+ LLVector3 spot_params = volobjp->getSpotLightParams();
+ clipboard["spot"]["fov"] = spot_params.mV[0];
+ clipboard["spot"]["focus"] = spot_params.mV[1];
+ clipboard["spot"]["ambiance"] = spot_params.mV[2];
+ }
+ }
+ }
+
+ if (volobjp && volobjp->isReflectionProbe())
+ {
+ clipboard["reflection_probe"]["is_box"] = volobjp->getReflectionProbeIsBox();
+ clipboard["reflection_probe"]["ambiance"] = volobjp->getReflectionProbeAmbiance();
+ clipboard["reflection_probe"]["near_clip"] = volobjp->getReflectionProbeNearClip();
+ clipboard["reflection_probe"]["dynamic"] = volobjp->getReflectionProbeIsDynamic();
+ }
+
+ mClipboardParams["light"] = clipboard;
+}
+
+void LLPanelVolume::onPasteLight()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp && mClipboardParams.has("light"))
+ {
+ return;
+ }
+
+ LLSD &clipboard = mClipboardParams["light"];
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Light Source
+ if (volobjp)
+ {
+ if (clipboard.has("light"))
+ {
+ volobjp->setIsLight(TRUE);
+ volobjp->setLightIntensity((F32)clipboard["light"]["intensity"].asReal());
+ volobjp->setLightRadius((F32)clipboard["light"]["radius"].asReal());
+ volobjp->setLightFalloff((F32)clipboard["light"]["falloff"].asReal());
+ F32 r = (F32)clipboard["light"]["r"].asReal();
+ F32 g = (F32)clipboard["light"]["g"].asReal();
+ F32 b = (F32)clipboard["light"]["b"].asReal();
+ volobjp->setLightSRGBColor(LLColor3(r, g, b));
+ }
+ else
+ {
+ volobjp->setIsLight(FALSE);
+ }
+
+ if (clipboard.has("spot"))
+ {
+ volobjp->setLightTextureID(clipboard["spot"]["id"].asUUID());
+ LLVector3 spot_params;
+ spot_params.mV[0] = (F32)clipboard["spot"]["fov"].asReal();
+ spot_params.mV[1] = (F32)clipboard["spot"]["focus"].asReal();
+ spot_params.mV[2] = (F32)clipboard["spot"]["ambiance"].asReal();
+ volobjp->setSpotLightParams(spot_params);
+ }
+
+ if (clipboard.has("reflection_probe"))
+ {
+ volobjp->setIsReflectionProbe(TRUE);
+ volobjp->setReflectionProbeIsBox(clipboard["reflection_probe"]["is_box"].asBoolean());
+ volobjp->setReflectionProbeAmbiance((F32)clipboard["reflection_probe"]["ambiance"].asReal());
+ volobjp->setReflectionProbeNearClip((F32)clipboard["reflection_probe"]["near_clip"].asReal());
+ volobjp->setReflectionProbeIsDynamic(clipboard["reflection_probe"]["dynamic"].asBoolean());
+ }
+ else
+ {
+ volobjp->setIsReflectionProbe(false);
+ }
+ }
+}
+
+void LLPanelVolume::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "features_paste")
+ {
+ onPasteFeatures();
+ }
+ else if (command == "light_paste")
+ {
+ onPasteLight();
+ }
+ // copy
+ else if (command == "features_copy")
+ {
+ onCopyFeatures();
+ }
+ else if (command == "light_copy")
+ {
+ onCopyLight();
+ }
+}
+
+bool LLPanelVolume::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "features_paste")
+ {
+ return mClipboardParams.has("features");
+ }
+ else if (command == "light_paste")
+ {
+ return mClipboardParams.has("light");
+ }
+ return false;
+}
+
// static
void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
{
@@ -927,6 +1298,27 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )
}
+//static
+void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ LLViewerObject* objectp = self->mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+
+ volobjp->setReflectionProbeAmbiance((F32)self->getChild<LLUICtrl>("Probe Ambiance")->getValue().asReal());
+ volobjp->setReflectionProbeNearClip((F32)self->getChild<LLUICtrl>("Probe Near Clip")->getValue().asReal());
+ volobjp->setReflectionProbeIsDynamic(self->getChild<LLUICtrl>("Probe Dynamic")->getValue().asBoolean());
+
+ std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type")->getValue().asString();
+
+ volobjp->setReflectionProbeIsBox(shape_type == "Box");
+}
+
// static
void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata )
{
@@ -942,7 +1334,7 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
LLViewerInventoryItem* item = gInventory.getItem(item_id);
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
- LLToolDragAndDrop::handleDropTextureProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
volobjp->setLightTextureID(asset_id);
}
@@ -950,6 +1342,15 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
//----------------------------------------------------------------------------
// static
+void LLPanelVolume::onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ self->sendIsReflectionProbe();
+}
+
+//----------------------------------------------------------------------------
+
+// static
void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
{
LLPanelVolume* self = (LLPanelVolume*) userdata;
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index 6e49ccb742..62a6d01b21 100644
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -37,6 +37,7 @@ class LLCheckBoxCtrl;
class LLTextBox;
class LLUICtrl;
class LLButton;
+class LLMenuButton;
class LLViewerObject;
class LLComboBox;
class LLColorSwatchCtrl;
@@ -56,12 +57,15 @@ public:
void refresh();
void sendIsLight();
+ void sendIsReflectionProbe();
void sendIsFlexible();
static bool precommitValidate(const LLSD& data);
static void onCommitIsLight( LLUICtrl* ctrl, void* userdata);
static void onCommitLight( LLUICtrl* ctrl, void* userdata);
+ static void onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata);
+ static void onCommitProbe(LLUICtrl* ctrl, void* userdata);
void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);
static void onCommitFlexible( LLUICtrl* ctrl, void* userdata);
void onCommitAnimatedMeshCheckbox(LLUICtrl* ctrl, void* userdata);
@@ -76,6 +80,13 @@ public:
static void setLightTextureID(const LLUUID &asset_id, const LLUUID &item_id, LLVOVolume* volobjp);
+ void onCopyFeatures();
+ void onPasteFeatures();
+ void onCopyLight();
+ void onPasteLight();
+
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
protected:
void getState();
@@ -123,6 +134,11 @@ protected:
LLSpinCtrl* mSpinPhysicsFriction;
LLSpinCtrl* mSpinPhysicsDensity;
LLSpinCtrl* mSpinPhysicsRestitution;
+
+ LLMenuButton* mMenuClipboardFeatures;
+ LLMenuButton* mMenuClipboardLight;
+
+ LLSD mClipboardParams;
};
#endif
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 94d20828ec..9b60d1ae2f 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -38,154 +38,11 @@
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
-// See EXT-4301.
-/**
- * class LLAvalineUpdater - observe the list of voice participants in session and check
- * presence of Avaline Callers among them.
- *
- * LLAvalineUpdater is a LLVoiceClientParticipantObserver. It provides two kinds of validation:
- * - whether Avaline caller presence among participants;
- * - whether watched Avaline caller still exists in voice channel.
- * Both validations have callbacks which will notify subscriber if any of event occur.
- *
- * @see findAvalineCaller()
- * @see checkIfAvalineCallersExist()
- */
-class LLAvalineUpdater : public LLVoiceClientParticipantObserver
-{
-public:
- typedef boost::function<void(const LLUUID& speaker_id)> process_avaline_callback_t;
-
- LLAvalineUpdater(process_avaline_callback_t found_cb, process_avaline_callback_t removed_cb)
- : mAvalineFoundCallback(found_cb)
- , mAvalineRemovedCallback(removed_cb)
- {
- LLVoiceClient::getInstance()->addObserver(this);
- }
- ~LLAvalineUpdater()
- {
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
- }
-
- /**
- * Adds UUID of Avaline caller to watch.
- *
- * @see checkIfAvalineCallersExist().
- */
- void watchAvalineCaller(const LLUUID& avaline_caller_id)
- {
- mAvalineCallers.insert(avaline_caller_id);
- }
-
- void onParticipantsChanged()
- {
- uuid_set_t participant_uuids;
- LLVoiceClient::getInstance()->getParticipantList(participant_uuids);
-
-
- // check whether Avaline caller exists among voice participants
- // and notify Participant List
- findAvalineCaller(participant_uuids);
-
- // check whether watched Avaline callers still present among voice participant
- // and remove if absents.
- checkIfAvalineCallersExist(participant_uuids);
- }
-
-private:
- typedef std::set<LLUUID> uuid_set_t;
-
- /**
- * Finds Avaline callers among voice participants and calls mAvalineFoundCallback.
- *
- * When Avatar is in group call with Avaline caller and then ends call Avaline caller stays
- * in Group Chat floater (exists in LLSpeakerMgr). If Avatar starts call with that group again
- * Avaline caller is added to voice channel AFTER Avatar is connected to group call.
- * But Voice Control Panel (VCP) is filled from session LLSpeakerMgr and there is no information
- * if a speaker is Avaline caller.
- *
- * In this case this speaker is created as avatar and will be recreated when it appears in
- * Avatar's Voice session.
- *
- * @see LLParticipantList::onAvalineCallerFound()
- */
- void findAvalineCaller(const uuid_set_t& participant_uuids)
- {
- uuid_set_t::const_iterator it = participant_uuids.begin(), it_end = participant_uuids.end();
-
- for(; it != it_end; ++it)
- {
- const LLUUID& participant_id = *it;
- if (!LLVoiceClient::getInstance()->isParticipantAvatar(participant_id))
- {
- LL_DEBUGS("Avaline") << "Avaline caller found among voice participants: " << participant_id << LL_ENDL;
-
- if (mAvalineFoundCallback)
- {
- mAvalineFoundCallback(participant_id);
- }
- }
- }
- }
-
- /**
- * Finds Avaline callers which are not anymore among voice participants and calls mAvalineRemovedCallback.
- *
- * The problem is when Avaline caller ends a call it is removed from Voice Client session but
- * still exists in LLSpeakerMgr. Server does not send such information.
- * This method implements a HUCK to notify subscribers that watched Avaline callers by class
- * are not anymore in the call.
- *
- * @see LLParticipantList::onAvalineCallerRemoved()
- */
- void checkIfAvalineCallersExist(const uuid_set_t& participant_uuids)
- {
- uuid_set_t::iterator it = mAvalineCallers.begin();
- uuid_set_t::const_iterator participants_it_end = participant_uuids.end();
-
- while (it != mAvalineCallers.end())
- {
- const LLUUID participant_id = *it;
- LL_DEBUGS("Avaline") << "Check avaline caller: " << participant_id << LL_ENDL;
- bool not_found = participant_uuids.find(participant_id) == participants_it_end;
- if (not_found)
- {
- LL_DEBUGS("Avaline") << "Watched Avaline caller is not found among voice participants: " << participant_id << LL_ENDL;
-
- // notify Participant List
- if (mAvalineRemovedCallback)
- {
- mAvalineRemovedCallback(participant_id);
- }
-
- // remove from the watch list
- mAvalineCallers.erase(it++);
- }
- else
- {
- ++it;
- }
- }
- }
-
- process_avaline_callback_t mAvalineFoundCallback;
- process_avaline_callback_t mAvalineRemovedCallback;
-
- uuid_set_t mAvalineCallers;
-};
-
LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) :
LLConversationItemSession(data_source->getSessionID(), root_view_model),
mSpeakerMgr(data_source),
mValidateSpeakerCallback(NULL)
{
-
- mAvalineUpdater = new LLAvalineUpdater(boost::bind(&LLParticipantList::onAvalineCallerFound, this, _1),
- boost::bind(&LLParticipantList::onAvalineCallerRemoved, this, _1));
-
mSpeakerAddListener = new SpeakerAddListener(*this);
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
mSpeakerClearListener = new SpeakerClearListener(*this);
@@ -243,32 +100,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewMode
LLParticipantList::~LLParticipantList()
{
- delete mAvalineUpdater;
-}
-
-/*
- Seems this method is not necessary after onAvalineCallerRemoved was implemented;
-
- It does nothing because list item is always created with correct class type for Avaline caller.
- For now Avaline Caller is removed from the LLSpeakerMgr List when it is removed from the Voice Client
- session.
- This happens in two cases: if Avaline Caller ends call itself or if Resident ends group call.
-
- Probably Avaline caller should be removed from the LLSpeakerMgr list ONLY if it ends call itself.
- Asked in EXT-4301.
-*/
-void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
-{
- removeParticipant(participant_id);
- // re-add avaline caller with a correct class instance.
- addAvatarIDExceptAgent(participant_id);
-}
-
-void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
-{
- LL_DEBUGS("Avaline") << "Removing avaline caller from the list: " << participant_id << LL_ENDL;
-
- mSpeakerMgr->removeAvalineSpeaker(participant_id);
}
void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
@@ -386,7 +217,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
// Create a participant view model instance
participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
- mAvalineUpdater->watchAvalineCaller(avatar_id);
}
// *TODO : Need to update the online/offline status of the participant
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 3a3ae76604..14c0a63692 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -32,7 +32,6 @@
class LLSpeakerMgr;
class LLUICtrl;
-class LLAvalineUpdater;
class LLParticipantList : public LLConversationItemSession
{
@@ -133,8 +132,6 @@ protected:
};
private:
- void onAvalineCallerFound(const LLUUID& participant_id);
- void onAvalineCallerRemoved(const LLUUID& participant_id);
/**
* Adjusts passed participant to work properly.
@@ -156,7 +153,6 @@ private:
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
validate_speaker_callback_t mValidateSpeakerCallback;
- LLAvalineUpdater* mAvalineUpdater;
};
#endif // LL_PARTICIPANTLIST_H
diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp
index 6e3e375488..a7011dfad5 100644
--- a/indra/newview/llpatchvertexarray.cpp
+++ b/indra/newview/llpatchvertexarray.cpp
@@ -69,11 +69,9 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p
// (The -1 is there because an LLSurface has a buffer of 1 on
// its East and North edges).
U32 power_of_two = 1;
- U32 surface_order = 0;
while (power_of_two < (surface_width-1))
{
power_of_two *= 2;
- surface_order += 1;
}
if (power_of_two == (surface_width-1))
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index 852b39f442..17b8ec0683 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -61,7 +61,8 @@
#define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus"
-#define CAP_SERVICE_OBJECT_LINKSETS "RegionObjects"
+#define CAP_SERVICE_GET_OBJECT_LINKSETS "RegionObjects"
+#define CAP_SERVICE_SET_OBJECT_LINKSETS "ObjectNavMeshProperties"
#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
#define CAP_SERVICE_CHARACTERS "CharacterProperties"
@@ -244,7 +245,7 @@ void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_re
}
else
{
- std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
+ std::string objectLinksetsURL = getRetrieveObjectLinksetsURLForCurrentRegion();
std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
{
@@ -273,7 +274,7 @@ void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLP
{
LLPathfindingObjectListPtr emptyLinksetListPtr;
- std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
+ std::string objectLinksetsURL = getChangeObjectLinksetsURLForCurrentRegion();
std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
{
@@ -755,9 +756,14 @@ std::string LLPathfindingManager::getRetrieveNavMeshURLForRegion(LLViewerRegion
return getCapabilityURLForRegion(pRegion, CAP_SERVICE_RETRIEVE_NAVMESH);
}
-std::string LLPathfindingManager::getObjectLinksetsURLForCurrentRegion() const
+std::string LLPathfindingManager::getRetrieveObjectLinksetsURLForCurrentRegion() const
{
- return getCapabilityURLForCurrentRegion(CAP_SERVICE_OBJECT_LINKSETS);
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_GET_OBJECT_LINKSETS);
+}
+
+std::string LLPathfindingManager::getChangeObjectLinksetsURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_SET_OBJECT_LINKSETS);
}
std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
index a44cd892da..bb44f780c8 100644
--- a/indra/newview/llpathfindingmanager.h
+++ b/indra/newview/llpathfindingmanager.h
@@ -122,7 +122,8 @@ private:
std::string getNavMeshStatusURLForCurrentRegion() const;
std::string getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const;
std::string getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const;
- std::string getObjectLinksetsURLForCurrentRegion() const;
+ std::string getRetrieveObjectLinksetsURLForCurrentRegion() const;
+ std::string getChangeObjectLinksetsURLForCurrentRegion() const;
std::string getTerrainLinksetsURLForCurrentRegion() const;
std::string getCharactersURLForCurrentRegion() const;
std::string getAgentStateURLForRegion(LLViewerRegion *pRegion) const;
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 9bc77393dc..9bf771db8a 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -163,12 +163,16 @@ void LLPersistentNotificationStorage::loadNotifications()
LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
}
-void LLPersistentNotificationStorage::initialize()
+void LLPersistentNotificationStorage::reset()
{
- std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml";
- setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name));
- setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+ std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml";
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name));
+ setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+}
+void LLPersistentNotificationStorage::initialize()
+{
+ reset();
LLNotifications::instance().getChannel("Persistent")->
connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
}
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
index 1fb4487286..335d85aaf6 100644
--- a/indra/newview/llpersistentnotificationstorage.h
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -52,6 +52,7 @@ public:
void saveNotifications();
void loadNotifications();
+ void reset();
protected:
diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp
index 5bfe5c9941..9603ee6329 100644
--- a/indra/newview/llphysicsshapebuilderutil.cpp
+++ b/indra/newview/llphysicsshapebuilderutil.cpp
@@ -29,7 +29,7 @@
#include "llphysicsshapebuilderutil.h"
/* static */
-void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut )
+void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut)
{
const LLProfileParams& profile_params = volume_params.getProfileParams();
const LLPathParams& path_params = volume_params.getPathParams();
@@ -191,6 +191,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
if ( volume_params.shouldForceConvex() )
{
+ // Server distinguishes between convex of a prim vs isSculpt, but we don't care.
specOut.mType = PhysicsShapeSpecification::USER_CONVEX;
}
// Make a simpler convex shape if we can.
@@ -199,6 +200,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
{
specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;
}
+ else if (volume_params.isMeshSculpt() &&
+ // Check overall dimensions, not individual triangles.
+ (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ||
+ scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ||
+ scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE
+ ) )
+ {
+ // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't.
+ specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;
+ }
else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy)
{
specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT;
diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h
index bd5b7d799c..b3b100296f 100644
--- a/indra/newview/llphysicsshapebuilderutil.h
+++ b/indra/newview/llphysicsshapebuilderutil.h
@@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f;
const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f;
const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE;
const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE;
+const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f;
class LLPhysicsVolumeParams : public LLVolumeParams
{
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index 5629438415..3c27964ec5 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -40,7 +40,7 @@ public:
{
Params()
{
- filter_asset_type = "landmark";
+ filter_asset_types = "landmark";
}
};
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index c267c3c699..30d0a22ef0 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -332,7 +332,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
else
{
ECameraPreset new_camera_preset = (ECameraPreset)gSavedSettings.getU32("CameraPresetType");
- bool new_camera_offsets = false;
if (IS_CAMERA)
{
if (isDefaultCameraPreset(name))
@@ -354,7 +353,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
{
new_camera_preset = CAMERA_PRESET_CUSTOM;
}
- new_camera_offsets = (!isDefaultCameraPreset(name) || (ECameraPreset)gSavedSettings.getU32("CameraPresetType") != new_camera_preset);
}
for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
{
diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h
index 9ac15d1639..ab60f4c008 100644
--- a/indra/newview/llpreview.h
+++ b/indra/newview/llpreview.h
@@ -83,7 +83,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual void onOpen(const LLSD& key);
- void setAuxItem( const LLInventoryItem* item );
+ virtual void setAuxItem( const LLInventoryItem* item );
static void onBtnCopyToInv(void* userdata);
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 39cdb6fb04..759e7859f2 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -347,9 +347,6 @@ BOOL LLPreviewGesture::postBuild()
LLTextBox* text;
LLCheckBoxCtrl* check;
- edit = getChild<LLLineEditor>("name");
- edit->setKeystrokeCallback(onKeystrokeCommit, this);
-
edit = getChild<LLLineEditor>("desc");
edit->setKeystrokeCallback(onKeystrokeCommit, this);
@@ -482,9 +479,6 @@ BOOL LLPreviewGesture::postBuild()
{
getChild<LLUICtrl>("desc")->setValue(item->getDescription());
getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
-
- getChild<LLUICtrl>("name")->setValue(item->getName());
- getChild<LLLineEditor>("name")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
}
return LLPreview::postBuild();
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 230def5362..3fd4f51559 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -866,7 +866,10 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
buffer[nread] = '\0';
fclose(file);
- mEditor->setText(LLStringExplicit(buffer));
+ std::string text = std::string(buffer);
+ LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab());
+
+ mEditor->setText(text);
delete[] buffer;
return true;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index a32dc8beda..5043250e08 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -601,7 +601,10 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)
buffer[nread] = '\0';
fclose(file);
- mEditor->setText(LLStringExplicit(buffer));
+ std::string text = std::string(buffer);
+ LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab());
+
+ mEditor->setText(text);
delete[] buffer;
return true;
@@ -1199,7 +1202,7 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask)
void LLScriptEdCore::onBtnLoadFromFile( void* data )
{
- (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false);
}
void LLScriptEdCore::loadScriptFromFile(const std::vector<std::string>& filenames, void* data)
@@ -1240,7 +1243,7 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata )
if( self->mSaveCallback )
{
- (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName);
}
}
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index cd7b93aba7..975e2bb910 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -296,7 +296,7 @@ void LLPreviewTexture::saveAs()
return;
std::string filename = getItem() ? LLDir::getScrubbedFileName(getItem()->getName()) : LLStringUtil::null;
- (new LLFilePickerReplyThread(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename);
}
void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenames)
@@ -367,7 +367,10 @@ void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
// add space for dimensions and aspect ratio
S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
-
+ if (getChild<LLLayoutPanel>("buttons_panel")->getVisible())
+ {
+ info_height += getChild<LLLayoutPanel>("buttons_panel")->getRect().getHeight();
+ }
LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
@@ -412,6 +415,16 @@ void LLPreviewTexture::openToSave()
mPreviewToSave = TRUE;
}
+void LLPreviewTexture::hideCtrlButtons()
+{
+ getChildView("desc txt")->setVisible(false);
+ getChildView("desc")->setVisible(false);
+ getChild<LLLayoutStack>("preview_stack")->collapsePanel(getChild<LLLayoutPanel>("buttons_panel"), true);
+ getChild<LLLayoutPanel>("buttons_panel")->setVisible(false);
+ getChild<LLComboBox>("combo_aspect_ratio")->setCurrentByIndex(0); //unconstrained
+ reshape(getRect().getWidth(), getRect().getHeight());
+}
+
// static
void LLPreviewTexture::onFileLoadedForSave(BOOL success,
LLViewerFetchedTexture *src_vi,
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index 9b6a843875..16db51332e 100644
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
@@ -67,6 +67,8 @@ public:
static void onSaveAsBtn(void* data);
+ void hideCtrlButtons();
+
/*virtual*/ void setObjectID(const LLUUID& object_id);
protected:
void init();
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 83b0c4f1bf..0faf6bf889 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -42,14 +42,6 @@ bool LLRecentPeople::add(const LLUUID& id, const LLSD& userdata)
if (is_not_group_id)
{
- // For each avaline call the id of caller is different even if
- // the phone number is the same.
- // To avoid duplication of avaline list items in the recent list
- // of panel People, deleting id's with similar phone number.
- const LLUUID& caller_id = getIDByPhoneNumber(userdata);
- if (caller_id.notNull())
- mPeople.erase(caller_id);
-
//[] instead of insert to replace existing id->llsd["date"] with new date value
mPeople[id] = userdata;
mChangedSignal();
@@ -90,35 +82,6 @@ const LLSD& LLRecentPeople::getData(const LLUUID& id) const
return no_data;
}
-bool LLRecentPeople::isAvalineCaller(const LLUUID& id) const
-{
- recent_people_t::const_iterator it = mPeople.find(id);
-
- if (it != mPeople.end())
- {
- const LLSD& user = it->second;
- return user["avaline_call"].asBoolean();
- }
-
- return false;
-}
-
-const LLUUID& LLRecentPeople::getIDByPhoneNumber(const LLSD& userdata)
-{
- if (!userdata["avaline_call"].asBoolean())
- return LLUUID::null;
-
- for (recent_people_t::const_iterator it = mPeople.begin(); it != mPeople.end(); ++it)
- {
- const LLSD& user_info = it->second;
-
- if (user_info["call_number"].asString() == userdata["call_number"].asString())
- return it->first;
- }
-
- return LLUUID::null;
-}
-
// virtual
bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index 18b669ff4f..1b322f2c0a 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -62,9 +62,7 @@ public:
* @param id avatar to add.
*
* @param userdata additional information about last interaction party.
- * For example when last interaction party is not an avatar
- * but an avaline caller, additional info (such as phone
- * number, session id and etc.) should be added.
+ * For example session id can be added.
*
* @return false if the avatar is in the list already, true otherwise
*/
@@ -97,13 +95,6 @@ public:
const LLSD& getData(const LLUUID& id) const;
/**
- * Checks whether specific participant is an avaline caller
- *
- * @param id identifier of specific participant
- */
- bool isAvalineCaller(const LLUUID& id) const;
-
- /**
* Set callback to be called when the list changed.
*
* Multiple callbacks can be set.
@@ -122,8 +113,6 @@ public:
private:
- const LLUUID& getIDByPhoneNumber(const LLSD& userdata);
-
typedef std::map<LLUUID, LLSD> recent_people_t;
recent_people_t mPeople;
signal_t mChangedSignal;
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
new file mode 100644
index 0000000000..ef611966ed
--- /dev/null
+++ b/indra/newview/llreflectionmap.cpp
@@ -0,0 +1,274 @@
+/**
+ * @file llreflectionmap.cpp
+ * @brief LLReflectionMap class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llreflectionmap.h"
+#include "pipeline.h"
+#include "llviewerwindow.h"
+#include "llviewerregion.h"
+
+extern F32SecondsImplicit gFrameTimeSeconds;
+
+LLReflectionMap::LLReflectionMap()
+{
+}
+
+void LLReflectionMap::update(U32 resolution, U32 face)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ mLastUpdateTime = gFrameTimeSeconds;
+ llassert(mCubeArray.notNull());
+ llassert(mCubeIndex != -1);
+ //llassert(LLPipeline::sRenderDeferred);
+
+ // make sure we don't walk off the edge of the render target
+ while (resolution > gPipeline.mRT->deferredScreen.getWidth() ||
+ resolution > gPipeline.mRT->deferredScreen.getHeight())
+ {
+ resolution /= 2;
+ }
+ gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic());
+}
+
+void LLReflectionMap::autoAdjustOrigin()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ if (mGroup)
+ {
+ const LLVector4a* bounds = mGroup->getBounds();
+ auto* node = mGroup->getOctreeNode();
+
+ if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN)
+ {
+ // for terrain, make probes float a couple meters above the highest point in the surface patch
+ mOrigin = bounds[0];
+ mOrigin.getF32ptr()[2] += bounds[1].getF32ptr()[2] + 3.f;
+
+ // update radius to encompass bounding box
+ LLVector4a d;
+ d.setAdd(bounds[0], bounds[1]);
+ d.sub(mOrigin);
+ mRadius = d.getLength3().getF32();
+ mPriority = 1;
+ }
+ else if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
+ {
+ mPriority = 1;
+ // cast a ray towards 8 corners of bounding box
+ // nudge origin towards center of empty space
+
+ if (!node)
+ {
+ return;
+ }
+
+ if (node->isLeaf() || node->getChildCount() > 1 || node->getElementCount() > 0)
+ { // use center of object bounding box for leaf nodes or nodes with multiple child nodes
+ mOrigin = bounds[0];
+
+ LLVector4a start;
+ LLVector4a end;
+
+ LLVector4a size = bounds[1];
+
+ LLVector4a corners[] =
+ {
+ { 1, 1, 1 },
+ { -1, 1, 1 },
+ { 1, -1, 1 },
+ { -1, -1, 1 },
+ { 1, 1, -1 },
+ { -1, 1, -1 },
+ { 1, -1, -1 },
+ { -1, -1, -1 }
+ };
+
+ for (int i = 0; i < 8; ++i)
+ {
+ corners[i].mul(size);
+ corners[i].add(bounds[0]);
+ }
+
+ LLVector4a extents[2];
+ extents[0].setAdd(bounds[0], bounds[1]);
+ extents[1].setSub(bounds[0], bounds[1]);
+
+ bool hit = false;
+ for (int i = 0; i < 8; ++i)
+ {
+ int face = -1;
+ LLVector4a intersection;
+ LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], true, false, true, &face, &intersection);
+ if (drawable != nullptr)
+ {
+ hit = true;
+ update_min_max(extents[0], extents[1], intersection);
+ }
+ else
+ {
+ update_min_max(extents[0], extents[1], corners[i]);
+ }
+ }
+
+ if (hit)
+ {
+ mOrigin.setAdd(extents[0], extents[1]);
+ mOrigin.mul(0.5f);
+ }
+
+ // make sure radius encompasses all objects
+ LLSimdScalar r2 = 0.0;
+ for (int i = 0; i < 8; ++i)
+ {
+ LLVector4a v;
+ v.setSub(corners[i], mOrigin);
+
+ LLSimdScalar d = v.dot3(v);
+
+ if (d > r2)
+ {
+ r2 = d;
+ }
+ }
+
+ mRadius = llmax(sqrtf(r2.getF32()), 8.f);
+ }
+ else
+ {
+ // user placed probe
+ mPriority = 2;
+
+ // use center of octree node volume for nodes that are just branches without data
+ mOrigin = node->getCenter();
+
+ // update radius to encompass entire octree node volume
+ mRadius = node->getSize().getLength3().getF32();
+
+ //mOrigin = bounds[0];
+ //mRadius = bounds[1].getLength3().getF32();
+
+ }
+ }
+ }
+ else if (mViewerObject)
+ {
+ mPriority = 64;
+ mOrigin.load3(mViewerObject->getPositionAgent().mV);
+ mRadius = mViewerObject->getScale().mV[0]*0.5f;
+ }
+}
+
+bool LLReflectionMap::intersects(LLReflectionMap* other)
+{
+ // TODO: incorporate getBox
+ LLVector4a delta;
+ delta.setSub(other->mOrigin, mOrigin);
+
+ F32 dist = delta.dot3(delta).getF32();
+
+ F32 r2 = mRadius + other->mRadius;
+
+ r2 *= r2;
+
+ return dist < r2;
+}
+
+extern LLControlGroup gSavedSettings;
+
+F32 LLReflectionMap::getAmbiance()
+{
+ F32 ret = 0.f;
+ if (mViewerObject && mViewerObject->getVolume())
+ {
+ ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance();
+ }
+
+ return ret;
+}
+
+F32 LLReflectionMap::getNearClip()
+{
+ const F32 MINIMUM_NEAR_CLIP = 0.1f;
+
+ F32 ret = 0.f;
+
+ if (mViewerObject && mViewerObject->getVolume())
+ {
+ ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeNearClip();
+ }
+
+ return llmax(ret, MINIMUM_NEAR_CLIP);
+}
+
+bool LLReflectionMap::getIsDynamic()
+{
+ if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
+ mViewerObject &&
+ mViewerObject->getVolume())
+ {
+ return ((LLVOVolume*)mViewerObject)->getReflectionProbeIsDynamic();
+ }
+
+ return false;
+}
+
+bool LLReflectionMap::getBox(LLMatrix4& box)
+{
+ if (mViewerObject)
+ {
+ LLVolume* volume = mViewerObject->getVolume();
+ if (volume)
+ {
+ LLVOVolume* vobjp = (LLVOVolume*)mViewerObject;
+
+ if (vobjp->getReflectionProbeIsBox())
+ {
+ glh::matrix4f mv(gGLModelView);
+ glh::matrix4f scale;
+ LLVector3 s = vobjp->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
+ mRadius = s.magVec();
+ scale.set_scale(glh::vec3f(s.mV));
+ if (vobjp->mDrawable != nullptr)
+ {
+ glh::matrix4f rm((F32*)vobjp->mDrawable->getWorldMatrix().mMatrix);
+
+ glh::matrix4f rt((F32*)vobjp->getRelativeXform().mMatrix);
+
+ mv = mv * rm * scale; // *rt;
+ mv = mv.inverse();
+
+ box = LLMatrix4(mv.m);
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
new file mode 100644
index 0000000000..cf0bc2ff27
--- /dev/null
+++ b/indra/newview/llreflectionmap.h
@@ -0,0 +1,102 @@
+/**
+ * @file llreflectionmap.h
+ * @brief LLReflectionMap class declaration
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#pragma once
+
+#include "llcubemaparray.h"
+#include "llmemory.h"
+
+class LLSpatialGroup;
+class LLViewerObject;
+
+class alignas(16) LLReflectionMap : public LLRefCount
+{
+ LL_ALIGN_NEW
+public:
+ // allocate an environment map of the given resolution
+ LLReflectionMap();
+
+ // update this environment map
+ // resolution - size of cube map to generate
+ void update(U32 resolution, U32 face);
+
+ // for volume partition probes, try to place this probe in the best spot
+ void autoAdjustOrigin();
+
+ // return true if given Reflection Map's influence volume intersect's with this one's
+ bool intersects(LLReflectionMap* other);
+
+ // Get the ambiance value to use for this probe
+ F32 getAmbiance();
+
+ // Get the near clip plane distance to use for this probe
+ F32 getNearClip();
+
+ // Return true if this probe should include avatars in its reflection map
+ bool getIsDynamic();
+
+ // get the encoded bounding box of this probe's influence volume
+ // will only return a box if this probe is associated with a VOVolume
+ // with its reflection probe influence volume to to VOLUME_TYPE_BOX
+ // return false if no bounding box (treat as sphere influence volume)
+ bool getBox(LLMatrix4& box);
+
+ // point at which environment map was last generated from (in agent space)
+ LLVector4a mOrigin;
+
+ // distance from viewer camera
+ F32 mDistance;
+
+ // radius of this probe's affected area
+ F32 mRadius = 16.f;
+
+ // last time this probe was updated (or when its update timer got reset)
+ F32 mLastUpdateTime = 0.f;
+
+ // last time this probe was bound for rendering
+ F32 mLastBindTime = 0.f;
+
+ // cube map used to sample this environment map
+ LLPointer<LLCubeMapArray> mCubeArray;
+ S32 mCubeIndex = -1; // index into cube map array or -1 if not currently stored in cube map array
+
+ // index into array packed by LLReflectionMapManager::getReflectionMaps
+ // WARNING -- only valid immediately after call to getReflectionMaps
+ S32 mProbeIndex = -1;
+
+ // set of any LLReflectionMaps that intersect this map (maintained by LLReflectionMapManager
+ std::vector<LLReflectionMap*> mNeighbors;
+
+ // spatial group this probe is tracking (if any)
+ LLSpatialGroup* mGroup = nullptr;
+
+ // viewer object this probe is tracking (if any)
+ LLViewerObject* mViewerObject = nullptr;
+
+ // what priority should this probe have (higher is higher priority)
+ U32 mPriority = 1;
+};
+
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
new file mode 100644
index 0000000000..19f0a8d089
--- /dev/null
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -0,0 +1,920 @@
+/**
+ * @file llreflectionmapmanager.cpp
+ * @brief LLReflectionMapManager class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llreflectionmapmanager.h"
+#include "llviewercamera.h"
+#include "llspatialpartition.h"
+#include "llviewerregion.h"
+#include "pipeline.h"
+#include "llviewershadermgr.h"
+#include "llviewercontrol.h"
+#include "llenvironment.h"
+#include "llstartup.h"
+
+extern BOOL gCubeSnapshot;
+extern BOOL gTeleportDisplay;
+
+LLReflectionMapManager::LLReflectionMapManager()
+{
+ for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i)
+ {
+ mCubeFree[i] = true;
+ }
+
+ // cube index 0 is reserved for the fallback probe
+ mCubeFree[0] = false;
+}
+
+struct CompareReflectionMapDistance
+{
+
+};
+
+
+struct CompareProbeDistance
+{
+ bool operator()(const LLPointer<LLReflectionMap>& lhs, const LLPointer<LLReflectionMap>& rhs)
+ {
+ return lhs->mDistance < rhs->mDistance;
+ }
+};
+
+// helper class to seed octree with probes
+void LLReflectionMapManager::update()
+{
+ if (!LLPipeline::sReflectionProbesEnabled || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE)
+ {
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(!gCubeSnapshot); // assert a snapshot is not in progress
+ if (LLAppViewer::instance()->logoutRequestSent())
+ {
+ return;
+ }
+
+ // =============== TODO -- move to an init function =================
+ initReflectionMaps();
+
+ if (!mRenderTarget.isComplete())
+ {
+ U32 color_fmt = GL_RGB16F;
+ const bool use_depth_buffer = true;
+ const bool use_stencil_buffer = false;
+ U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample
+ mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE);
+ }
+
+ if (mMipChain.empty())
+ {
+ U32 res = LL_REFLECTION_PROBE_RESOLUTION;
+ U32 count = log2((F32)res) + 0.5f;
+
+ mMipChain.resize(count);
+ for (int i = 0; i < count; ++i)
+ {
+ mMipChain[i].allocate(res, res, GL_RGBA16F, false, false, LLTexUnit::TT_RECT_TEXTURE);
+ res /= 2;
+ }
+ }
+
+
+ if (mDefaultProbe.isNull())
+ {
+ mDefaultProbe = addProbe();
+ mDefaultProbe->mDistance = -4096.f; // hack to make sure the default probe is always first in sort order
+ mDefaultProbe->mRadius = 4096.f;
+ }
+
+ mDefaultProbe->mOrigin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
+
+ LLVector4a camera_pos;
+ camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
+
+ // process kill list
+ for (auto& probe : mKillList)
+ {
+ auto const & iter = std::find(mProbes.begin(), mProbes.end(), probe);
+ if (iter != mProbes.end())
+ {
+ deleteProbe(iter - mProbes.begin());
+ }
+ }
+
+ mKillList.clear();
+
+ // process create list
+ for (auto& probe : mCreateList)
+ {
+ mProbes.push_back(probe);
+ }
+
+ mCreateList.clear();
+
+ if (mProbes.empty())
+ {
+ return;
+ }
+
+ bool did_update = false;
+
+ static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
+ bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME;
+
+ LLReflectionMap* closestDynamic = nullptr;
+
+ LLReflectionMap* oldestProbe = nullptr;
+
+ if (mUpdatingProbe != nullptr)
+ {
+ did_update = true;
+ doProbeUpdate();
+ }
+
+ for (int i = 0; i < mProbes.size(); ++i)
+ {
+ LLReflectionMap* probe = mProbes[i];
+ if (probe->getNumRefs() == 1)
+ { // no references held outside manager, delete this probe
+ deleteProbe(i);
+ --i;
+ continue;
+ }
+
+ probe->mProbeIndex = i;
+
+ LLVector4a d;
+
+ if (!did_update &&
+ i < mReflectionProbeCount &&
+ (oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime))
+ {
+ oldestProbe = probe;
+ }
+
+ if (realtime &&
+ closestDynamic == nullptr &&
+ probe->mCubeIndex != -1 &&
+ probe->getIsDynamic())
+ {
+ closestDynamic = probe;
+ }
+
+ if (probe != mDefaultProbe)
+ {
+ d.setSub(camera_pos, probe->mOrigin);
+ probe->mDistance = d.getLength3().getF32() - probe->mRadius;
+ }
+ }
+
+ if (realtime && closestDynamic != nullptr)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime");
+ // update the closest dynamic probe realtime
+ closestDynamic->autoAdjustOrigin();
+ for (U32 i = 0; i < 6; ++i)
+ {
+ updateProbeFace(closestDynamic, i);
+ }
+ }
+
+ // switch to updating the next oldest probe
+ if (!did_update && oldestProbe != nullptr)
+ {
+ LLReflectionMap* probe = oldestProbe;
+ if (probe->mCubeIndex == -1)
+ {
+ probe->mCubeArray = mTexture;
+
+ probe->mCubeIndex = probe == mDefaultProbe ? 0 : allocateCubeIndex();
+ }
+
+ probe->autoAdjustOrigin();
+
+ mUpdatingProbe = probe;
+ doProbeUpdate();
+ }
+
+ // update distance to camera for all probes
+ std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance());
+}
+
+LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
+{
+ LLReflectionMap* probe = new LLReflectionMap();
+ probe->mGroup = group;
+
+ if (group)
+ {
+ probe->mOrigin = group->getOctreeNode()->getCenter();
+ }
+
+ if (gCubeSnapshot)
+ { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update
+ mCreateList.push_back(probe);
+ }
+ else
+ {
+ mProbes.push_back(probe);
+ }
+
+ return probe;
+}
+
+void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& maps)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ U32 count = 0;
+ U32 lastIdx = 0;
+ for (U32 i = 0; count < maps.size() && i < mProbes.size(); ++i)
+ {
+ mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested
+ if (mProbes[i]->mCubeIndex != -1)
+ {
+ mProbes[i]->mProbeIndex = count;
+ maps[count++] = mProbes[i];
+ }
+ else
+ {
+ mProbes[i]->mProbeIndex = -1;
+ }
+ lastIdx = i;
+ }
+
+ // set remaining probe indices to -1
+ for (U32 i = lastIdx+1; i < mProbes.size(); ++i)
+ {
+ mProbes[i]->mProbeIndex = -1;
+ }
+
+ // null terminate list
+ if (count < maps.size())
+ {
+ maps[count] = nullptr;
+ }
+}
+
+LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group)
+{
+#if 1
+ if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
+ {
+ OctreeNode* node = group->getOctreeNode();
+ F32 size = node->getSize().getF32ptr()[0];
+ if (size >= 15.f && size <= 17.f)
+ {
+ return addProbe(group);
+ }
+ }
+#endif
+
+#if 0
+ if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN)
+ {
+ OctreeNode* node = group->getOctreeNode();
+ F32 size = node->getSize().getF32ptr()[0];
+ if (size >= 15.f && size <= 17.f)
+ {
+ return addProbe(group);
+ }
+ }
+#endif
+ return nullptr;
+}
+
+LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vobj)
+{
+ llassert(vobj != nullptr);
+
+ LLReflectionMap* probe = new LLReflectionMap();
+ probe->mViewerObject = vobj;
+ probe->mOrigin.load3(vobj->getPositionAgent().mV);
+
+ if (gCubeSnapshot)
+ { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update
+ mCreateList.push_back(probe);
+ }
+ else
+ {
+ mProbes.push_back(probe);
+ }
+
+ return probe;
+}
+
+
+S32 LLReflectionMapManager::allocateCubeIndex()
+{
+ for (int i = 0; i < mReflectionProbeCount; ++i)
+ {
+ if (mCubeFree[i])
+ {
+ mCubeFree[i] = false;
+ return i;
+ }
+ }
+
+ // no cubemaps free, steal one from the back of the probe list
+ for (int i = mProbes.size() - 1; i >= mReflectionProbeCount; --i)
+ {
+ if (mProbes[i]->mCubeIndex != -1)
+ {
+ S32 ret = mProbes[i]->mCubeIndex;
+ mProbes[i]->mCubeIndex = -1;
+ mProbes[i]->mCubeArray = nullptr;
+ return ret;
+ }
+ }
+
+ llassert(false); // should never fail to allocate, something is probably wrong with mCubeFree
+ return -1;
+}
+
+void LLReflectionMapManager::deleteProbe(U32 i)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ LLReflectionMap* probe = mProbes[i];
+
+ llassert(probe != mDefaultProbe);
+
+ if (probe->mCubeIndex != -1)
+ { // mark the cube index used by this probe as being free
+ mCubeFree[probe->mCubeIndex] = true;
+ }
+ if (mUpdatingProbe == probe)
+ {
+ mUpdatingProbe = nullptr;
+ mUpdatingFace = 0;
+ }
+
+ // remove from any Neighbors lists
+ for (auto& other : probe->mNeighbors)
+ {
+ auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
+ llassert(iter != other->mNeighbors.end());
+ other->mNeighbors.erase(iter);
+ }
+
+ mProbes.erase(mProbes.begin() + i);
+}
+
+
+void LLReflectionMapManager::doProbeUpdate()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(mUpdatingProbe != nullptr);
+
+ updateProbeFace(mUpdatingProbe, mUpdatingFace);
+
+ if (++mUpdatingFace == 6)
+ {
+ updateNeighbors(mUpdatingProbe);
+ mUpdatingProbe = nullptr;
+ mUpdatingFace = 0;
+ }
+}
+
+void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
+{
+ // hacky hot-swap of camera specific render targets
+ gPipeline.mRT = &gPipeline.mAuxillaryRT;
+ probe->update(mRenderTarget.getWidth(), face);
+ gPipeline.mRT = &gPipeline.mMainRT;
+
+ S32 targetIdx = mReflectionProbeCount;
+
+ if (probe != mUpdatingProbe)
+ { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel
+ targetIdx += 1;
+ }
+
+ gGL.setColorMask(true, true);
+
+ // downsample to placeholder map
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ LLGLDisable cull(GL_CULL_FACE);
+
+ gReflectionMipProgram.bind();
+
+ gGL.matrixMode(gGL.MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.matrixMode(gGL.MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.flush();
+ U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2;
+
+ S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f;
+
+ S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
+ S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
+
+ LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen;
+ LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen;
+
+ for (int i = 0; i < mMipChain.size(); ++i)
+ {
+ LL_PROFILE_GPU_ZONE("probe mip");
+ mMipChain[i].bindTarget();
+ if (i == 0)
+ {
+
+ gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1]));
+ }
+
+ gGL.getTexUnit(depthChannel)->bind(depth_rt, true);
+
+ static LLStaticHashedString resScale("resScale");
+ static LLStaticHashedString znear("znear");
+ static LLStaticHashedString zfar("zfar");
+
+ gReflectionMipProgram.uniform1f(resScale, (F32) (1 << i));
+ gReflectionMipProgram.uniform1f(znear, probe->getNearClip());
+ gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP);
+
+ gGL.begin(gGL.QUADS);
+
+ gGL.texCoord2f(0, 0);
+ gGL.vertex2f(-1, -1);
+
+ gGL.texCoord2f(res, 0);
+ gGL.vertex2f(1, -1);
+
+ gGL.texCoord2f(res, res);
+ gGL.vertex2f(1, 1);
+
+ gGL.texCoord2f(0, res);
+ gGL.vertex2f(-1, 1);
+ gGL.end();
+ gGL.flush();
+
+ res /= 2;
+
+ S32 mip = i - (mMipChain.size() - mips);
+
+ if (mip >= 0)
+ {
+ LL_PROFILE_GPU_ZONE("probe mip copy");
+ mTexture->bind(0);
+ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res);
+ //if (i == 0)
+ //{
+ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
+ //}
+ mTexture->unbind();
+ }
+ mMipChain[i].flush();
+ }
+
+ gGL.popMatrix();
+ gGL.matrixMode(gGL.MM_MODELVIEW);
+ gGL.popMatrix();
+
+ gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE);
+ gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE);
+ gReflectionMipProgram.unbind();
+ }
+
+ if (face == 5)
+ {
+ //generate radiance map
+ gRadianceGenProgram.bind();
+ mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTexture->bind(channel);
+ static LLStaticHashedString sSourceIdx("sourceIdx");
+ gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx);
+
+ mMipChain[0].bindTarget();
+ U32 res = mMipChain[0].getWidth();
+
+ for (int i = 0; i < mMipChain.size(); ++i)
+ {
+ LL_PROFILE_GPU_ZONE("probe radiance gen");
+ static LLStaticHashedString sMipLevel("mipLevel");
+ static LLStaticHashedString sRoughness("roughness");
+ static LLStaticHashedString sWidth("u_width");
+
+ gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));
+ gRadianceGenProgram.uniform1f(sMipLevel, i);
+ gRadianceGenProgram.uniform1i(sWidth, mMipChain[i].getWidth());
+
+ for (int cf = 0; cf < 6; ++cf)
+ { // for each cube face
+ LLCoordFrame frame;
+ frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+ F32 mat[16];
+ frame.getOpenGLRotation(mat);
+ gGL.loadMatrix(mat);
+
+ mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4);
+
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+ }
+
+ if (i != mMipChain.size() - 1)
+ {
+ res /= 2;
+ glViewport(0, 0, res, res);
+ }
+ }
+
+ gRadianceGenProgram.unbind();
+
+ //generate irradiance map
+ gIrradianceGenProgram.bind();
+ channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTexture->bind(channel);
+
+ gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx);
+ mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ int start_mip = 0;
+ // find the mip target to start with based on irradiance map resolution
+ for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip)
+ {
+ if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION)
+ {
+ break;
+ }
+ }
+
+ //for (int i = start_mip; i < mMipChain.size(); ++i)
+ {
+ int i = start_mip;
+ LL_PROFILE_GPU_ZONE("probe irradiance gen");
+ glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight());
+ for (int cf = 0; cf < 6; ++cf)
+ { // for each cube face
+ LLCoordFrame frame;
+ frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+ F32 mat[16];
+ frame.getOpenGLRotation(mat);
+ gGL.loadMatrix(mat);
+
+ mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4);
+
+ S32 res = mMipChain[i].getWidth();
+ mIrradianceMaps->bind(channel);
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+ mTexture->bind(channel);
+ }
+ }
+
+ mMipChain[0].flush();
+
+ gIrradianceGenProgram.unbind();
+ }
+}
+
+void LLReflectionMapManager::rebuild()
+{
+ for (auto& probe : mProbes)
+ {
+ probe->mLastUpdateTime = 0.f;
+ }
+}
+
+void LLReflectionMapManager::shift(const LLVector4a& offset)
+{
+ for (auto& probe : mProbes)
+ {
+ probe->mOrigin.add(offset);
+ }
+}
+
+void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (mDefaultProbe == probe)
+ {
+ return;
+ }
+
+ //remove from existing neighbors
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear");
+
+ for (auto& other : probe->mNeighbors)
+ {
+ auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
+ llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly
+ other->mNeighbors.erase(iter);
+ }
+
+ probe->mNeighbors.clear();
+ }
+
+ // search for new neighbors
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search");
+ for (auto& other : mProbes)
+ {
+ if (other != mDefaultProbe && other != probe)
+ {
+ if (probe->intersects(other))
+ {
+ probe->mNeighbors.push_back(other);
+ other->mNeighbors.push_back(probe);
+ }
+ }
+ }
+ }
+}
+
+void LLReflectionMapManager::updateUniforms()
+{
+ if (!LLPipeline::sReflectionProbesEnabled)
+ {
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ // structure for packing uniform buffer object
+ // see class3/deferred/reflectionProbeF.glsl
+ struct ReflectionProbeData
+ {
+ LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; // object bounding box as needed
+ LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space
+ LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance)
+ GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4];
+ GLint refNeighbor[4096];
+ GLint refmapCount;
+ };
+
+ mReflectionMaps.resize(mReflectionProbeCount);
+ getReflectionMaps(mReflectionMaps);
+
+ ReflectionProbeData rpd;
+
+ // load modelview matrix into matrix 4a
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+ LLVector4a oa; // scratch space for transformed origin
+
+ S32 count = 0;
+ U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors
+
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ F32 minimum_ambiance = psky->getReflectionProbeAmbiance();
+
+ for (auto* refmap : mReflectionMaps)
+ {
+ if (refmap == nullptr)
+ {
+ break;
+ }
+
+ llassert(refmap->mProbeIndex == count);
+ llassert(mReflectionMaps[refmap->mProbeIndex] == refmap);
+
+ llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged
+
+ {
+ //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refSphere");
+
+ modelview.affineTransform(refmap->mOrigin, oa);
+ rpd.refSphere[count].set(oa.getF32ptr());
+ rpd.refSphere[count].mV[3] = refmap->mRadius;
+ }
+
+ rpd.refIndex[count][0] = refmap->mCubeIndex;
+ llassert(nc % 4 == 0);
+ rpd.refIndex[count][1] = nc / 4;
+ rpd.refIndex[count][3] = refmap->mPriority;
+
+ // for objects that are reflection probes, use the volume as the influence volume of the probe
+ // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres
+ if (refmap->getBox(rpd.refBox[count]))
+ { // negate priority to indicate this probe has a box influence volume
+ rpd.refIndex[count][3] = -rpd.refIndex[count][3];
+ }
+
+ rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance()), 0.f, 0.f, 0.f);
+
+ S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors
+ {
+ //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors");
+ //pack neghbor list
+ for (auto& neighbor : refmap->mNeighbors)
+ {
+ if (ni >= 4096)
+ { // out of space
+ break;
+ }
+
+ GLint idx = neighbor->mProbeIndex;
+ if (idx == -1)
+ {
+ continue;
+ }
+
+ // this neighbor may be sampled
+ rpd.refNeighbor[ni++] = idx;
+ }
+ }
+
+ if (nc == ni)
+ {
+ //no neighbors, tag as empty
+ rpd.refIndex[count][1] = -1;
+ }
+ else
+ {
+ rpd.refIndex[count][2] = ni - nc;
+
+ // move the cursor forward
+ nc = ni;
+ if (nc % 4 != 0)
+ { // jump to next power of 4 for compatibility with ivec4
+ nc += 4 - (nc % 4);
+ }
+ }
+
+
+ count++;
+ }
+
+ rpd.refmapCount = count;
+
+ //copy rpd into uniform buffer object
+ if (mUBO == 0)
+ {
+ glGenBuffers(1, &mUBO);
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer");
+ glBindBuffer(GL_UNIFORM_BUFFER, mUBO);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ }
+}
+
+void LLReflectionMapManager::setUniforms()
+{
+ if (!LLPipeline::sReflectionProbesEnabled)
+ {
+ return;
+ }
+
+ if (mUBO == 0)
+ {
+ updateUniforms();
+ }
+ glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO);
+}
+
+
+void renderReflectionProbe(LLReflectionMap* probe)
+{
+ F32* po = probe->mOrigin.getF32ptr();
+
+ //draw orange line from probe to neighbors
+ gGL.flush();
+ gGL.diffuseColor4f(1, 0.5f, 0, 1);
+ gGL.begin(gGL.LINES);
+ for (auto& neighbor : probe->mNeighbors)
+ {
+ gGL.vertex3fv(po);
+ gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
+ }
+ gGL.end();
+ gGL.flush();
+
+#if 0
+ LLSpatialGroup* group = probe->mGroup;
+ if (group)
+ { // draw lines from corners of object aabb to reflection probe
+
+ const LLVector4a* bounds = group->getBounds();
+ LLVector4a o = bounds[0];
+
+ gGL.flush();
+ gGL.diffuseColor4f(0, 0, 1, 1);
+ F32* c = o.getF32ptr();
+
+ const F32* bc = bounds[0].getF32ptr();
+ const F32* bs = bounds[1].getF32ptr();
+
+ // daaw blue lines from corners to center of node
+ gGL.begin(gGL.LINES);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] + bs[2]);
+
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] - bs[2]);
+ gGL.end();
+
+ //draw yellow line from center of node to reflection probe origin
+ gGL.flush();
+ gGL.diffuseColor4f(1, 1, 0, 1);
+ gGL.begin(gGL.LINES);
+ gGL.vertex3fv(c);
+ gGL.vertex3fv(po);
+ gGL.end();
+ gGL.flush();
+ }
+#endif
+}
+
+void LLReflectionMapManager::renderDebug()
+{
+ gDebugProgram.bind();
+
+ for (auto& probe : mProbes)
+ {
+ renderReflectionProbe(probe);
+ }
+
+ gDebugProgram.unbind();
+}
+
+void LLReflectionMapManager::initReflectionMaps()
+{
+ if (mTexture.isNull())
+ {
+ mReflectionProbeCount = llclamp(gSavedSettings.getS32("RenderReflectionProbeCount"), 1, LL_MAX_REFLECTION_PROBE_COUNT);
+
+ mTexture = new LLCubeMapArray();
+
+ // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
+ mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 4, mReflectionProbeCount + 2);
+
+ mIrradianceMaps = new LLCubeMapArray();
+ mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE);
+ }
+
+ if (mVertexBuffer.isNull())
+ {
+ U32 mask = LLVertexBuffer::MAP_VERTEX;
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, GL_STATIC_DRAW);
+ buff->allocateBuffer(4, 0, TRUE);
+
+ LLStrider<LLVector3> v;
+
+ buff->getVertexStrider(v);
+
+ v[0] = LLVector3(-1, -1, -1);
+ v[1] = LLVector3(1, -1, -1);
+ v[2] = LLVector3(-1, 1, -1);
+ v[3] = LLVector3(1, 1, -1);
+
+ buff->flush();
+
+ mVertexBuffer = buff;
+ }
+}
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
new file mode 100644
index 0000000000..e0a2c00db3
--- /dev/null
+++ b/indra/newview/llreflectionmapmanager.h
@@ -0,0 +1,163 @@
+/**
+ * @file llreflectionmapmanager.h
+ * @brief LLReflectionMapManager class declaration
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#pragma once
+
+#include "llreflectionmap.h"
+#include "llrendertarget.h"
+#include "llcubemaparray.h"
+#include "llcubemap.h"
+
+class LLSpatialGroup;
+class LLViewerObject;
+
+// number of reflection probes to keep in vram
+#define LL_MAX_REFLECTION_PROBE_COUNT 256
+
+// reflection probe resolution
+#define LL_REFLECTION_PROBE_RESOLUTION 128
+#define LL_IRRADIANCE_MAP_RESOLUTION 64
+
+// reflection probe mininum scale
+#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f;
+
+class alignas(16) LLReflectionMapManager
+{
+ LL_ALIGN_NEW
+public:
+ enum class DetailLevel
+ {
+ STATIC_ONLY = 0,
+ STATIC_AND_DYNAMIC,
+ REALTIME = 2
+ };
+
+ // allocate an environment map of the given resolution
+ LLReflectionMapManager();
+
+ // maintain reflection probes
+ void update();
+
+ // add a probe for the given spatial group
+ LLReflectionMap* addProbe(LLSpatialGroup* group = nullptr);
+
+ // Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size()
+ // If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr.
+ // maps -- presized array of Reflection Map pointers
+ void getReflectionMaps(std::vector<LLReflectionMap*>& maps);
+
+ // called by LLSpatialGroup constructor
+ // If spatial group should receive a Reflection Probe, will create one for the specified spatial group
+ LLReflectionMap* registerSpatialGroup(LLSpatialGroup* group);
+
+ // presently hacked into LLViewerObject::setTE
+ // Used by LLViewerObjects that are Reflection Probes
+ // Guaranteed to not return null
+ LLReflectionMap* registerViewerObject(LLViewerObject* vobj);
+
+ // force an update of all probes
+ void rebuild();
+
+ // called on region crossing to "shift" probes into new coordinate frame
+ void shift(const LLVector4a& offset);
+
+ // debug display, called from llspatialpartition if reflection
+ // probe debug display is active
+ void renderDebug();
+
+ // call once at startup to allocate cubemap arrays
+ void initReflectionMaps();
+
+private:
+ friend class LLPipeline;
+
+ // delete the probe with the given index in mProbes
+ void deleteProbe(U32 i);
+
+ // get a free cube index
+ // if no cube indices are free, free one starting from the back of the probe list
+ S32 allocateCubeIndex();
+
+ // update the neighbors of the given probe
+ void updateNeighbors(LLReflectionMap* probe);
+
+ // update UBO used for rendering (call only once per render pipe flush)
+ void updateUniforms();
+
+ // bind UBO used for rendering
+ void setUniforms();
+
+ // render target for cube snapshots
+ // used to generate mipmaps without doing a copy-to-texture
+ LLRenderTarget mRenderTarget;
+
+ std::vector<LLRenderTarget> mMipChain;
+
+ // storage for reflection probe radiance maps (plus two scratch space cubemaps)
+ LLPointer<LLCubeMapArray> mTexture;
+
+ // vertex buffer for pushing verts to filter shaders
+ LLPointer<LLVertexBuffer> mVertexBuffer;
+
+ // storage for reflection probe irradiance maps
+ LLPointer<LLCubeMapArray> mIrradianceMaps;
+
+ // array indicating if a particular cubemap is free
+ bool mCubeFree[LL_MAX_REFLECTION_PROBE_COUNT];
+
+ // start tracking the given spatial group
+ void trackGroup(LLSpatialGroup* group);
+
+ // perform an update on the currently updating Probe
+ void doProbeUpdate();
+
+ // update the specified face of the specified probe
+ void updateProbeFace(LLReflectionMap* probe, U32 face);
+
+ // list of active reflection maps
+ std::vector<LLPointer<LLReflectionMap> > mProbes;
+
+ // list of reflection maps to kill
+ std::vector<LLPointer<LLReflectionMap> > mKillList;
+
+ // list of reflection maps to create
+ std::vector<LLPointer<LLReflectionMap> > mCreateList;
+
+ // handle to UBO
+ U32 mUBO = 0;
+
+ // list of maps being used for rendering
+ std::vector<LLReflectionMap*> mReflectionMaps;
+
+ LLReflectionMap* mUpdatingProbe = nullptr;
+ U32 mUpdatingFace = 0;
+
+ LLPointer<LLReflectionMap> mDefaultProbe; // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0)
+
+ // number of reflection probes to use for rendering (based on saved setting RenderReflectionProbeCount)
+ U32 mReflectionProbeCount;
+};
+
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 055ccd5818..f4ace52faa 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -213,7 +213,12 @@ void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url,
if (!status)
{
- observer->setErrorStatus(status.getStatus(), status.getMessage());
+ std::string message = status.getMessage();
+ if (message.empty())
+ {
+ message = status.toString();
+ }
+ observer->setErrorStatus(status.getStatus(), message);
}
else
{
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 2e44dc1459..49d5aa3e14 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -445,14 +445,14 @@ void LLSceneMonitor::calcDiffAggregate()
if(mDiffState == EXECUTE_DIFF)
{
- glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject);
+ glBeginQuery(GL_SAMPLES_PASSED, mQueryObject);
}
gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff);
if(mDiffState == EXECUTE_DIFF)
{
- glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+ glEndQuery(GL_SAMPLES_PASSED);
mDiffState = WAIT_ON_RESULT;
}
@@ -483,11 +483,11 @@ void LLSceneMonitor::fetchQueryResult()
mDiffState = WAITING_FOR_NEXT_DIFF;
GLuint available = 0;
- glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE, &available);
if(available)
{
GLuint count = 0;
- glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_ARB, &count);
+ glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT, &count);
mDiffResult = sqrtf(count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio)); //0.5 -> (front face + back face)
diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp
index f7aa63e34d..e250f9bc7a 100644
--- a/indra/newview/llsceneview.cpp
+++ b/indra/newview/llsceneview.cpp
@@ -266,14 +266,11 @@ void LLSceneView::draw()
U32 count = triangles[idx].size();
- U32 total = 0;
-
gGL.begin(LLRender::LINE_STRIP);
//plot triangles
for (U32 i = 0; i < count; ++i)
{
U32 tri_count = triangles[idx][i];
- total += tri_count;
F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom;
F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft;
@@ -290,15 +287,8 @@ void LLSceneView::draw()
gGL.end();
gGL.flush();
- U32 total_visible = 0;
count = visible_triangles[idx].size();
- for (U32 i = 0; i < count; ++i)
- {
- U32 tri_count = visible_triangles[idx][i];
- total_visible += tri_count;
- }
-
std::string label = llformat("%s Object Triangle Counts (Ktris) -- Visible: %.2f/%.2f (%.2f KB Visible)",
category[idx], total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, total_visible_bytes[idx]/1024.f);
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index e033cae3ab..31f11eb8ef 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -41,9 +41,9 @@ namespace ll
struct PanelData;
struct TabContainerData;
- typedef boost::shared_ptr< SearchableItem > SearchableItemPtr;
- typedef boost::shared_ptr< PanelData > PanelDataPtr;
- typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr;
+ typedef std::shared_ptr< SearchableItem > SearchableItemPtr;
+ typedef std::shared_ptr< PanelData > PanelDataPtr;
+ typedef std::shared_ptr< TabContainerData > TabContainerDataPtr;
typedef std::vector< TabContainerData > tTabContainerDataList;
typedef std::vector< SearchableItemPtr > tSearchableItemList;
@@ -55,7 +55,7 @@ namespace ll
LLView const *mView;
ll::ui::SearchableControl const *mCtrl;
- std::vector< boost::shared_ptr< SearchableItem > > mChildren;
+ std::vector< std::shared_ptr< SearchableItem > > mChildren;
virtual ~SearchableItem();
@@ -68,8 +68,8 @@ namespace ll
LLPanel const *mPanel;
std::string mLabel;
- std::vector< boost::shared_ptr< SearchableItem > > mChildren;
- std::vector< boost::shared_ptr< PanelData > > mChildPanel;
+ std::vector< std::shared_ptr< SearchableItem > > mChildren;
+ std::vector< std::shared_ptr< PanelData > > mChildPanel;
virtual ~PanelData();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 82a165cb35..2475900d0e 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -63,6 +63,7 @@
#include "llfloatertools.h"
#include "llframetimer.h"
#include "llfocusmgr.h"
+#include "llgltfmateriallist.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llinventorymodel.h"
@@ -310,14 +311,29 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle)
{
struct f : public LLSelectedNodeFunctor
{
+ f(bool a, LLSelectMgr* p) : mAvatarOverridesPersist(a), mManager(p) {}
+ bool mAvatarOverridesPersist;
+ LLSelectMgr* mManager;
virtual bool apply(LLSelectNode* node)
{
+ if (mAvatarOverridesPersist)
+ {
+ LLViewerObject* object = node->getObject();
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ mManager->mAvatarOverridesMap.emplace(avatar->getID(), AvatarPositionOverride(node->mLastPositionLocal, node->mLastRotation, object));
+ }
+ }
+ }
node->mLastPositionLocal.setVec(0, 0, 0);
node->mLastRotation = LLQuaternion();
node->mLastScale.setVec(0, 0, 0);
return true;
}
- } func;
+ } func(mAllowSelectAvatar, this);
selected_handle->applyToNodes(&func);
}
@@ -351,6 +367,93 @@ void LLSelectMgr::overrideObjectUpdates()
getSelection()->applyToNodes(&func);
}
+void LLSelectMgr::resetAvatarOverrides()
+{
+ mAvatarOverridesMap.clear();
+}
+
+void LLSelectMgr::overrideAvatarUpdates()
+{
+ if (mAvatarOverridesMap.size() == 0)
+ {
+ return;
+ }
+
+ if (!mAllowSelectAvatar || !gFloaterTools)
+ {
+ resetAvatarOverrides();
+ return;
+ }
+
+ if (!gFloaterTools->getVisible() && getSelection()->isEmpty())
+ {
+ // when user switches selection, floater is invisible and selection is empty
+ LLToolset *toolset = LLToolMgr::getInstance()->getCurrentToolset();
+ if (toolset->isShowFloaterTools()
+ && toolset->isToolSelected(0)) // Pie tool
+ {
+ resetAvatarOverrides();
+ return;
+ }
+ }
+
+ // remove selected avatars from this list,
+ // but set object overrides to make sure avatar won't snap back
+ struct f : public LLSelectedNodeFunctor
+ {
+ f(LLSelectMgr* p) : mManager(p) {}
+ LLSelectMgr* mManager;
+ virtual bool apply(LLSelectNode* selectNode)
+ {
+ LLViewerObject* object = selectNode->getObject();
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ uuid_av_override_map_t::iterator iter = mManager->mAvatarOverridesMap.find(avatar->getID());
+ if (iter != mManager->mAvatarOverridesMap.end())
+ {
+ if (selectNode->mLastPositionLocal.isExactlyZero())
+ {
+ selectNode->mLastPositionLocal = iter->second.mLastPositionLocal;
+ }
+ if (selectNode->mLastRotation == LLQuaternion())
+ {
+ selectNode->mLastRotation = iter->second.mLastRotation;
+ }
+ mManager->mAvatarOverridesMap.erase(iter);
+ }
+ }
+ }
+ return true;
+ }
+ } func(this);
+ getSelection()->applyToNodes(&func);
+
+ // Override avatar positions
+ uuid_av_override_map_t::iterator it = mAvatarOverridesMap.begin();
+ while (it != mAvatarOverridesMap.end())
+ {
+ if (it->second.mObject->isDead())
+ {
+ it = mAvatarOverridesMap.erase(it);
+ }
+ else
+ {
+ if (!it->second.mLastPositionLocal.isExactlyZero())
+ {
+ it->second.mObject->setPosition(it->second.mLastPositionLocal);
+ }
+ if (it->second.mLastRotation != LLQuaternion())
+ {
+ it->second.mObject->setRotation(it->second.mLastRotation);
+ }
+ it++;
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// Select just the object, not any other group members.
//-----------------------------------------------------------------------------
@@ -886,7 +989,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
// Can't select yourself
if (objectp->mID == gAgentID
- && !LLSelectMgr::getInstance()->mAllowSelectAvatar)
+ && !mAllowSelectAvatar)
{
continue;
}
@@ -1066,8 +1169,8 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
return;
}
- if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
- || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
+ if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
+ || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
{
// only select my own objects
return;
@@ -1644,6 +1747,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
bool texture_copied = false;
+ bool updated = false;
for (S32 te = 0; te < num_tes; ++te)
{
if (node->isTESelected(te))
@@ -1652,22 +1756,68 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
// without making any copies
if (!texture_copied)
{
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
texture_copied = true;
}
// apply texture for the selected faces
add(LLStatViewer::EDIT_TEXTURE, 1);
object->setTEImage(te, image);
- dialog_refresh_all();
-
- // send the update to the simulator
- object->sendTEUpdate();
+ updated = true;
}
}
+
+ if (updated) // not nessesary? sendTEUpdate update supposed to be done by sendfunc
+ {
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ object->sendTEUpdate();
+ }
}
}
+void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item)
+{
+ if (!item)
+ {
+ return;
+ }
+
+ LLUUID asset_id = item->getAssetUUID();
+
+ for (iterator iter = begin(); iter != end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = (*iter)->getObject();
+ if (!object)
+ {
+ continue;
+ }
+
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ bool material_copied = false;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ //(no-copy) materials must be moved to the object's inventory only once
+ // without making any copies
+ if (!material_copied && asset_id.notNull())
+ {
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ material_copied = true;
+ }
+
+ // apply texture for the selected faces
+ //add(LLStatViewer::EDIT_TEXTURE, 1);
+ object->setRenderMaterialID(te, asset_id, false /*will be sent later*/);
+ }
+ }
+ }
+}
+
+
//-----------------------------------------------------------------------------
// selectionSetImage()
//-----------------------------------------------------------------------------
@@ -1760,6 +1910,148 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
}
//-----------------------------------------------------------------------------
+// selectionSetGLTFMaterial()
+//-----------------------------------------------------------------------------
+void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
+{
+ // First for (no copy) textures and multiple object selection
+ LLViewerInventoryItem* item = gInventory.getItem(mat_id);
+ if (item
+ && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
+ && (mSelectedObjects->getNumNodes() > 1))
+ {
+ LL_WARNS() << "Attempted to apply no-copy material to multiple objects"
+ << LL_ENDL;
+ return;
+ }
+
+ struct f : public LLSelectedTEFunctor
+ {
+ LLViewerInventoryItem* mItem;
+ LLUUID mMatId;
+ f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mMatId(id) {}
+ bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (objectp && !objectp->permModify())
+ {
+ return false;
+ }
+ LLUUID asset_id = mMatId;
+ if (mItem)
+ {
+ asset_id = mItem->getAssetUUID();
+ }
+
+ if (asset_id.notNull() && !objectp->hasRenderMaterialParams())
+ {
+ // make sure param section exists
+ objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/);
+ }
+
+ if (te != -1)
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (asset_id.notNull())
+ {
+ tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id));
+ }
+ else
+ {
+ tep->setGLTFMaterial(nullptr);
+ }
+
+ objectp->faceMappingChanged();
+ gPipeline.markTextured(objectp->mDrawable);
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ param_block->setMaterial(te, asset_id);
+ }
+ }
+ else // Shouldn't happen?
+ {
+ S32 num_faces = objectp->getNumTEs();
+ for (S32 face = 0; face < num_faces; face++)
+ {
+ LLTextureEntry* tep = objectp->getTE(face);
+ if (asset_id.notNull())
+ {
+ tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id));
+ }
+ else
+ {
+ tep->setGLTFMaterial(nullptr);
+ }
+
+ objectp->faceMappingChanged();
+ gPipeline.markTextured(objectp->mDrawable);
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ param_block->setMaterial(face, asset_id);
+ }
+ }
+ }
+
+ return true;
+ }
+ };
+
+ if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ {
+ getSelection()->applyNoCopyPbrMaterialToTEs(item);
+ }
+ else
+ {
+ f setfunc(item, mat_id);
+ getSelection()->applyToTEs(&setfunc);
+ }
+
+ struct g : public LLSelectedObjectFunctor
+ {
+ LLViewerInventoryItem* mItem;
+ g(LLViewerInventoryItem* item) : mItem(item) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object && !object->permModify())
+ {
+ return false;
+ }
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ object->setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+
+ if (!mItem)
+ {
+ // 1 particle effect per object
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+ effectp->setSourceObject(gAgentAvatarp);
+ effectp->setTargetObject(object);
+ effectp->setDuration(LL_HUD_DUR_SHORT);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ }
+
+ dialog_refresh_all();
+ object->sendTEUpdate();
+ return true;
+ }
+ } sendfunc(item);
+ getSelection()->applyToObjects(&sendfunc);
+}
+
+//-----------------------------------------------------------------------------
// selectionSetColor()
//-----------------------------------------------------------------------------
void LLSelectMgr::selectionSetColor(const LLColor4 &color)
@@ -1936,6 +2228,59 @@ BOOL LLSelectMgr::selectionRevertTextures()
return revert_successful;
}
+void LLSelectMgr::selectionRevertGLTFMaterials()
+{
+ struct f : public LLSelectedTEFunctor
+ {
+ LLObjectSelectionHandle mSelectedObjects;
+ f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
+ bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (objectp && !objectp->permModify())
+ {
+ return false;
+ }
+
+ LLSelectNode* nodep = mSelectedObjects->findNode(objectp);
+ if (nodep && te < (S32)nodep->mSavedGLTFMaterials.size())
+ {
+ LLUUID asset_id = nodep->mSavedGLTFMaterials[te];
+ objectp->setRenderMaterialID(te, asset_id, false /*wait for bulk update*/);
+ }
+ return true;
+ }
+ } setfunc(mSelectedObjects);
+ getSelection()->applyToTEs(&setfunc);
+
+ struct g : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object && !object->permModify())
+ {
+ return false;
+ }
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ object->setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+
+ object->sendTEUpdate();
+ return true;
+ }
+ } sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
+}
+
void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
{
struct f : public LLSelectedTEFunctor
@@ -1965,7 +2310,7 @@ void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
{
LLViewerObject *object = mSelectedObjects->getFirstRootObject();
if (!object) return;
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
@@ -2025,7 +2370,7 @@ void LLSelectMgr::selectionSetShiny(U8 shiny, const LLUUID &image_id)
{
LLViewerObject *object = mSelectedObjects->getFirstRootObject();
if (!object) return;
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
@@ -5526,6 +5871,17 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
// this should be the only place that saved textures is called
node->saveTextures(texture_ids);
}
+
+ if (can_copy && can_transfer && node->getObject()->getVolume())
+ {
+ uuid_vec_t material_ids;
+ LLVOVolume* vobjp = (LLVOVolume*)node->getObject();
+ for (int i = 0; i < vobjp->getNumTEs(); ++i)
+ {
+ material_ids.push_back(vobjp->getRenderMaterialID(i));
+ }
+ node->savedGLTFMaterials(material_ids);
+ }
}
node->mValid = TRUE;
@@ -5992,7 +6348,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
auto renderMeshSelection_f = [fogCfx, wireframe_selection](LLSelectNode* node, LLViewerObject* objectp, LLColor4 hlColor)
{
//Need to because crash on ATI 3800 (and similar cards) MAINT-5018
- LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
@@ -6277,10 +6633,29 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
}
saveTextures(nodep.mSavedTextures);
+ savedGLTFMaterials(nodep.mSavedGLTFMaterials);
}
LLSelectNode::~LLSelectNode()
{
+ LLSelectMgr *manager = LLSelectMgr::getInstance();
+ if (manager->mAllowSelectAvatar
+ && (!mLastPositionLocal.isExactlyZero()
+ || mLastRotation != LLQuaternion()))
+ {
+ LLViewerObject* object = getObject(); //isDead() check
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ // Avatar was moved and needs to stay that way
+ manager->mAvatarOverridesMap.emplace(avatar->getID(), LLSelectMgr::AvatarPositionOverride(mLastPositionLocal, mLastRotation, object));
+ }
+ }
+ }
+
+
delete mPermissions;
mPermissions = NULL;
}
@@ -6392,6 +6767,20 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)
}
}
+void LLSelectNode::savedGLTFMaterials(const uuid_vec_t& materials)
+{
+ if (mObject.notNull())
+ {
+ mSavedGLTFMaterials.clear();
+
+ for (uuid_vec_t::const_iterator materials_it = materials.begin();
+ materials_it != materials.end(); ++materials_it)
+ {
+ mSavedGLTFMaterials.push_back(*materials_it);
+ }
+ }
+}
+
void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
{
mTextureScaleRatios.clear();
@@ -6788,6 +7177,10 @@ void LLSelectMgr::updateSelectionCenter()
const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection
// center (tractor beam)
+ // override any avatar updates received
+ // Works only if avatar was repositioned
+ // and edit floater is visible
+ overrideAvatarUpdates();
//override any object updates received
//for selected objects
overrideObjectUpdates();
@@ -8183,6 +8576,7 @@ DEF_DUMMY_CHECK_FUNCTOR(int)
DEF_DUMMY_CHECK_FUNCTOR(LLColor4)
DEF_DUMMY_CHECK_FUNCTOR(LLMediaEntry)
DEF_DUMMY_CHECK_FUNCTOR(LLPointer<LLMaterial>)
+DEF_DUMMY_CHECK_FUNCTOR(LLPointer<LLGLTFMaterial>)
DEF_DUMMY_CHECK_FUNCTOR(std::string)
DEF_DUMMY_CHECK_FUNCTOR(std::vector<std::string>)
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index ce0316e610..573eea7a8a 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -187,6 +187,7 @@ public:
void saveColors();
void saveShinyColors();
void saveTextures(const uuid_vec_t& textures);
+ void savedGLTFMaterials(const uuid_vec_t& materials);
void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
@@ -224,6 +225,7 @@ public:
std::vector<LLColor4> mSavedColors;
std::vector<LLColor4> mSavedShinyColors;
uuid_vec_t mSavedTextures;
+ uuid_vec_t mSavedGLTFMaterials;
std::vector<LLVector3> mTextureScaleRatios;
std::vector<LLVector3> mSilhouetteVertices; // array of vertices to render silhouette of object
std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object
@@ -366,6 +368,7 @@ public:
* Then this only texture is used for all selected faces.
*/
void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
+ void applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item);
ESelectType getSelectType() const { return mSelectType; }
@@ -467,6 +470,30 @@ public:
void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
void overrideObjectUpdates();
+ void resetAvatarOverrides();
+ void overrideAvatarUpdates();
+
+ struct AvatarPositionOverride
+ {
+ AvatarPositionOverride();
+ AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) :
+ mLastPositionLocal(vec),
+ mLastRotation(quat),
+ mObject(obj)
+ {
+ }
+ LLVector3 mLastPositionLocal;
+ LLQuaternion mLastRotation;
+ LLPointer<LLViewerObject> mObject;
+ };
+
+ // Avatar overrides should persist even after selection
+ // was removed as long as edit floater is up
+ typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t;
+ uuid_av_override_map_t mAvatarOverridesMap;
+public:
+
+
// Returns the previous value of mForceSelection
BOOL setForceSelection(BOOL force);
@@ -603,12 +630,14 @@ public:
void selectionSetRestitution(F32 restitution);
void selectionSetMaterial(U8 material);
void selectionSetImage(const LLUUID& imageid); // could be item or asset id
+ void selectionSetGLTFMaterial(const LLUUID& mat_id); // could be item or asset id
void selectionSetColor(const LLColor4 &color);
void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
void selectionRevertColors();
void selectionRevertShinyColors();
BOOL selectionRevertTextures();
+ void selectionRevertGLTFMaterials();
void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id );
void selectionSetTexGen( U8 texgen );
void selectionSetShiny( U8 shiny, const LLUUID &image_id );
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 14a9f4aa30..f9b7c749b3 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -123,7 +123,7 @@ void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, cons
void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback)
{
- U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner();
+ U32 nextOwnerPerm = LLFloaterPerms::getNextOwnerPerms("Settings");
createInventoryItem(settings, nextOwnerPerm, parent_id, settings_name, callback);
}
@@ -667,17 +667,17 @@ void LLSettingsVOSky::updateSettings()
void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm();
+ LLVector3 light_direction = LLVector3(LLEnvironment::instance().getClampedLightNorm().mV);
LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT];
{
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin());
}
shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY];
{
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
// Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")
LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
@@ -690,25 +690,30 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
// * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
cloud_scroll[0] = -cloud_scroll[0];
vect_c_p_d1 += cloud_scroll;
- shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, vect_c_p_d1);
+ shader->uniform3fv(LLShaderMgr::CLOUD_POS_DENSITY1, LLVector3(vect_c_p_d1.mV));
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV);
- LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV);
+ // TODO -- make these getters return vec3s
+ LLVector3 sunDiffuse = LLVector3(psky->getSunlightColor().mV);
+ LLVector3 moonDiffuse = LLVector3(psky->getMoonlightColor().mV);
- shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
- shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
+ shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
- LLVector4 cloud_color(LLVector3(psky->getCloudColor().mV), 1.0);
- shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color);
+ shader->uniform3fv(LLShaderMgr::CLOUD_COLOR, LLVector3(psky->getCloudColor().mV));
}
shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY];
shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
- LLColor4 ambient(getTotalAmbient());
- shader->uniform4fv(LLShaderMgr::AMBIENT, LLVector4(ambient.mV));
+ LLColor3 ambient(getTotalAmbient());
+
+ shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));
+ shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, linearColor3v(getAmbientColor()/3.f)); // note magic number 3.f comes from SLIDER_SCALE_SUN_AMBIENT
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_LINEAR, linearColor3v(getSunlightColor()));
+ shader->uniform3fv(LLShaderMgr::MOONLIGHT_LINEAR,linearColor3v(getMoonlightColor()));
+ shader->uniform1f(LLShaderMgr::REFLECTION_PROBE_AMBIANCE, getReflectionProbeAmbiance());
shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, getIsSunUp() ? 1 : 0);
shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor());
@@ -720,6 +725,10 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
shader->uniform1f(LLShaderMgr::GAMMA, g);
shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, display_gamma);
+
+ shader->uniform3fv(LLShaderMgr::BLUE_HORIZON_LINEAR, linearColor3v(getBlueHorizon()/2.f)); // note magic number of 2.f comes from SLIDER_SCALE_BLUE_HORIZON_DENSITY
+ shader->uniform3fv(LLShaderMgr::BLUE_DENSITY_LINEAR, linearColor3v(getBlueDensity()/2.f));
+ shader->uniform1f(LLShaderMgr::HAZE_DENSITY_LINEAR, sRGBtoLinear(getHazeDensity()));
}
LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
@@ -758,6 +767,7 @@ LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
param_map[SETTING_SKY_DROPLET_RADIUS] = DefaultParam(LLShaderMgr::DROPLET_RADIUS, sky_defaults[SETTING_SKY_DROPLET_RADIUS]);
param_map[SETTING_SKY_ICE_LEVEL] = DefaultParam(LLShaderMgr::ICE_LEVEL, sky_defaults[SETTING_SKY_ICE_LEVEL]);
+ param_map[SETTING_REFLECTION_PROBE_AMBIANCE] = DefaultParam(LLShaderMgr::REFLECTION_PROBE_AMBIANCE, sky_defaults[SETTING_REFLECTION_PROBE_AMBIANCE]);
// AdvancedAtmospherics TODO
// Provide mappings for new shader params here
}
@@ -939,6 +949,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
+ LLDrawPoolAlpha::sWaterPlane = waterPlane;
+
shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV);
LLVector4 light_direction = env.getClampedLightNorm();
@@ -953,14 +965,16 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
F32 waterFogDensity = env.getCurrentWater()->getModifiedWaterFogDensity(underwater);
shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity);
- LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f);
+ LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor());
shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, linearColor3(fog_color).mV);
+
F32 blend_factor = env.getCurrentWater()->getBlendFactor();
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
// update to normal lightnorm, water shader itself will use rotated lightnorm as necessary
- shader->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
+ shader->uniform3fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
}
}
@@ -1026,12 +1040,39 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
std::set<std::string> framenames;
std::set<std::string> notfound;
+ // expected and correct folder sctructure is to have
+ // three folders in widnlight's root: days, water, skies
std::string base_path(gDirUtilp->getDirName(path));
std::string water_path(base_path);
std::string sky_path(base_path);
+ std::string day_path(base_path);
gDirUtilp->append(water_path, "water");
gDirUtilp->append(sky_path, "skies");
+ gDirUtilp->append(day_path, "days");
+
+ if (!gDirUtilp->fileExists(day_path))
+ {
+ LL_WARNS("SETTINGS") << "File " << name << ".xml is not in \"days\" folder." << LL_ENDL;
+ }
+
+ if (!gDirUtilp->fileExists(water_path))
+ {
+ LL_WARNS("SETTINGS") << "Failed to find accompaniying water folder for file " << name
+ << ".xml. Falling back to using default folder" << LL_ENDL;
+
+ water_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight");
+ gDirUtilp->append(water_path, "water");
+ }
+
+ if (!gDirUtilp->fileExists(sky_path))
+ {
+ LL_WARNS("SETTINGS") << "Failed to find accompaniying skies folder for file " << name
+ << ".xml. Falling back to using default folder" << LL_ENDL;
+
+ sky_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight");
+ gDirUtilp->append(sky_path, "skies");
+ }
newsettings[SETTING_NAME] = name;
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 7fa06f51e3..6216057c17 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -77,7 +77,7 @@ static LLPanelInjector<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info");
LLSidepanelTaskInfo::LLSidepanelTaskInfo()
{
setMouseOpaque(FALSE);
- LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this));
+ mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this));
}
@@ -85,6 +85,11 @@ LLSidepanelTaskInfo::~LLSidepanelTaskInfo()
{
if (sActivePanel == this)
sActivePanel = NULL;
+
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
}
// virtual
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index dc259cb22d..ac9c57f2e2 100644
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -154,6 +154,8 @@ private:
LLView* mDAE;
LLView* mDAN;
LLView* mDAF;
+
+ boost::signals2::connection mSelectionUpdateSlot;
};
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 3ab7707df8..61e9d261f7 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -554,9 +554,12 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO
sg_assert(mOctreeNode->getListenerCount() == 0);
setState(SG_INITIAL_STATE_MASK);
gPipeline.markRebuild(this, TRUE);
+
+ // let the reflection map manager know about this spatial group
+ mReflectionProbe = gPipeline.mReflectionMapManager.registerSpatialGroup(this);
- mRadius = 1;
- mPixelArea = 1024.f;
+ mRadius = 1;
+ mPixelArea = 1024.f;
}
void LLSpatialGroup::updateDistance(LLCamera &camera)
@@ -1010,11 +1013,11 @@ public:
virtual void processGroup(LLViewerOctreeGroup* base_group)
{
LLSpatialGroup* group = (LLSpatialGroup*)base_group;
- if (group->needsUpdate() ||
+ /*if (group->needsUpdate() ||
group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
{
group->doOcclusion(mCamera);
- }
+ }*/
gPipeline.markNotCulled(group, *mCamera);
}
};
@@ -1399,7 +1402,9 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
return 0;
}
-
+
+extern BOOL gCubeSnapshot;
+
S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
@@ -1418,7 +1423,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
LLOctreeCullShadow culler(&camera);
culler.traverse(mOctree);
}
- else if (mInfiniteFarClip || !LLPipeline::sUseFarClip)
+ else if (mInfiniteFarClip || (!LLPipeline::sUseFarClip && !gCubeSnapshot))
{
LLOctreeCullNoFarClip culler(&camera);
culler.traverse(mOctree);
@@ -1567,6 +1572,62 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
}
}
+// return false if drawable is rigged and:
+// - a linked rigged drawable has a different spatial group
+// - a linked rigged drawable face has the wrong draw order index
+bool check_rigged_group(LLDrawable* drawable)
+{
+ if (drawable->isState(LLDrawable::RIGGED))
+ {
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ LLDrawable* root = drawable->getRoot();
+
+ if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group)
+ {
+ llassert(false);
+ return false;
+ }
+
+ S32 last_draw_index = -1;
+ if (root->isState(LLDrawable::RIGGED))
+ {
+ for (auto& face : root->getFaces())
+ {
+ if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ {
+ llassert(false);
+ return false;
+ }
+ last_draw_index = face->getDrawOrderIndex();
+ }
+ }
+
+ for (auto& child : root->getVObj()->getChildren())
+ {
+ if (child->mDrawable->isState(LLDrawable::RIGGED))
+ {
+ for (auto& face : child->mDrawable->getFaces())
+ {
+ if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ {
+ llassert(false);
+ return false;
+ }
+ last_draw_index = face->getDrawOrderIndex();
+ }
+ }
+
+ if (child->mDrawable->getSpatialGroup() != group)
+ {
+ llassert(false);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
void renderOctree(LLSpatialGroup* group)
{
//render solid object bounding box, color
@@ -1576,7 +1637,7 @@ void renderOctree(LLSpatialGroup* group)
if (group->mBuilt > 0.f)
{
group->mBuilt -= 2.f * gFrameIntervalSeconds.value();
- if (group->mBufferUsage == GL_STATIC_DRAW_ARB)
+ if (group->mBufferUsage == GL_STATIC_DRAW)
{
col.setVec(1.0f, 0, 0, group->mBuilt*0.5f);
}
@@ -1586,7 +1647,7 @@ void renderOctree(LLSpatialGroup* group)
//col.setVec(1.0f, 1.0f, 0, sinf(group->mBuilt*3.14159f)*0.5f);
}
- if (group->mBufferUsage != GL_STATIC_DRAW_ARB)
+ if (group->mBufferUsage != GL_STATIC_DRAW)
{
LLGLDepthTest gl_depth(FALSE, FALSE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -1611,6 +1672,9 @@ void renderOctree(LLSpatialGroup* group)
{
continue;
}
+
+ llassert(check_rigged_group(drawable));
+
if (!group->getSpatialPartition()->isBridge())
{
gGL.pushMatrix();
@@ -1681,7 +1745,7 @@ void renderOctree(LLSpatialGroup* group)
}
else
{
- if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty()
+ if (group->mBufferUsage == GL_STATIC_DRAW && !group->isEmpty()
&& group->getSpatialPartition()->mRenderByGroup)
{
col.setVec(0.8f, 0.4f, 0.1f, 0.1f);
@@ -1738,7 +1802,7 @@ void renderOctree(LLSpatialGroup* group)
}
}*/
}
-
+
// LLSpatialGroup::OctreeNode* node = group->mOctreeNode;
// gGL.diffuseColor4f(0,1,0,1);
// drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
@@ -2610,14 +2674,12 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
gGL.diffuseColor4fv(line_color.mV);
gGL.syncMatrices();
{
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x20FF20 )
glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
}
gGL.diffuseColor4fv(color.mV);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
{
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x40FF40 )
glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
}
}
@@ -3028,7 +3090,7 @@ public:
}
- void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+ void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);
@@ -3070,7 +3132,7 @@ public:
}
gGL.begin(LLRender::TRIANGLES);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
iter != branch->getDataEnd();
++iter)
{
@@ -3156,7 +3218,6 @@ void renderRaycast(LLDrawable* drawablep)
gGL.diffuseColor4f(0,1,1,0.5f);
glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);
gGL.syncMatrices();
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x60FF60 );
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
@@ -3164,14 +3225,14 @@ void renderRaycast(LLDrawable* drawablep)
{
F32 t = 1.f;
- if (!face.mOctree)
+ if (!face.getOctree())
{
((LLVolumeFace*) &face)->createOctree();
}
LLRenderOctreeRaycast render(start, dir, &t);
- render.traverse(face.mOctree);
+ render.traverse(face.getOctree());
}
gGL.popMatrix();
@@ -3704,7 +3765,7 @@ void LLSpatialPartition::renderDebug()
//LLPipeline::RENDER_DEBUG_BUILD_QUEUE |
LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY |
- LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
+ LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
return;
}
@@ -3738,7 +3799,6 @@ void LLSpatialPartition::renderDebug()
LLOctreeRenderNonOccluded render_debug(camera);
render_debug.traverse(mOctree);
-
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
{
{
@@ -3787,7 +3847,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)
}
LL_ALIGN_PREFIX(16)
-class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry>
+class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>>
{
public:
LL_ALIGN_16(LLVector4a mStart);
@@ -3801,8 +3861,9 @@ public:
LLDrawable* mHit;
BOOL mPickTransparent;
BOOL mPickRigged;
+ BOOL mPickUnselectable;
- LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged,
+ LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable,
S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
: mStart(start),
mEnd(end),
@@ -3813,7 +3874,8 @@ public:
mTangent(tangent),
mHit(NULL),
mPickTransparent(pick_transparent),
- mPickRigged(pick_rigged)
+ mPickRigged(pick_rigged),
+ mPickUnselectable(pick_unselectable)
{
}
@@ -3898,7 +3960,7 @@ public:
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
if ((mPickRigged) || ((avatar->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
+ LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
if (hit)
{
mEnd = intersection;
@@ -3914,7 +3976,7 @@ public:
}
}
- if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mPickRigged, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
+ if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
{
mEnd = intersection; // shorten ray so we only find CLOSER hits
if (mIntersection)
@@ -3934,6 +3996,7 @@ public:
LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit, // return the face hit
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
@@ -3942,12 +4005,30 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co
)
{
- LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, face_hit, intersection, tex_coord, normal, tangent);
+ LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, face_hit, intersection, tex_coord, normal, tangent);
LLDrawable* drawable = intersect.check(mOctree);
return drawable;
}
+LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
+)
+
+{
+ LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, face_hit, intersection, tex_coord, normal, tangent);
+ LLDrawable* drawable = intersect.check(getOctreeNode());
+
+ return drawable;
+}
+
LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* texture, LLVertexBuffer* buffer,
bool selected,
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 6d3ef33801..0d16b818f1 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -41,6 +41,7 @@
#include "llviewercamera.h"
#include "llvector4a.h"
#include "llvoavatar.h"
+#include "llfetchedgltfmaterial.h"
#include <queue>
#include <unordered_map>
@@ -53,6 +54,7 @@ class LLSpatialPartition;
class LLSpatialBridge;
class LLSpatialGroup;
class LLViewerRegion;
+class LLReflectionMap;
void pushVerts(LLFace* face, U32 mask);
@@ -112,9 +114,16 @@ public:
LL_ALIGN_16(LLFace* mFace); //associated face
F32 mDistance;
U32 mDrawMode;
- LLMaterialPtr mMaterial; // If this is null, the following parameters are unused.
- LLMaterialID mMaterialID;
- U32 mShaderMask;
+
+ // Material pointer here is likely for debugging only and are immaterial (zing!)
+ LLMaterialPtr mMaterial;
+
+ // PBR material parameters
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
+
+ LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info
+
+ U32 mShaderMask;
U32 mBlendFuncSrc;
U32 mBlendFuncDst;
BOOL mHasGlow;
@@ -122,6 +131,7 @@ public:
const LLMatrix4* mSpecularMapMatrix;
LLPointer<LLViewerTexture> mNormalMap;
const LLMatrix4* mNormalMapMatrix;
+
LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
F32 mEnvIntensity;
F32 mAlphaMaskCutoff;
@@ -313,6 +323,18 @@ public:
void drawObjectBox(LLColor4 col);
+ LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+
LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;}
//LISTENER FUNCTIONS
@@ -355,6 +377,9 @@ public:
//used by LLVOAVatar to set render order in alpha draw pool to preserve legacy render order behavior
LLVOAvatar* mAvatarp = nullptr;
U32 mRenderOrder = 0;
+ // Reflection Probe associated with this node (if any)
+ LLPointer<LLReflectionMap> mReflectionProbe = nullptr;
+
} LL_ALIGN_POSTFIX(64);
class LLGeometryManager
@@ -382,6 +407,7 @@ public:
LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit, // return the face hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index abb936c3e5..ea671a130e 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -534,7 +534,7 @@ void LLSpeakerMgr::updateSpeakerList()
}
else if (mSpeakers.size() == 0)
{
- // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list
+ // For all other session type (ad-hoc, P2P), we use the initial participants targets list
for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
{
// Add buddies if they are on line, add any other avatar.
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index d1dbf72fe9..ed795b5155 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -245,14 +245,6 @@ public:
bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
/**
- * Removes avaline speaker.
- *
- * This is a HACK due to server does not send information that Avaline caller ends call.
- * It can be removed when server is updated. See EXT-4301 for details
- */
- bool removeAvalineSpeaker(const LLUUID& speaker_id) { return removeSpeaker(speaker_id); }
-
- /**
* Initializes mVoiceModerated depend on LLSpeaker::mModeratorMutedVoice of agent's participant.
*
* Is used only to implement workaround to initialize mVoiceModerated on first join to group chat. See EXT-6937
diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp
index c3eb70f850..0cdad86a76 100644
--- a/indra/newview/llsprite.cpp
+++ b/indra/newview/llsprite.cpp
@@ -190,7 +190,7 @@ void LLSprite::updateFace(LLFace &face)
{
LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0,
- GL_STREAM_DRAW_ARB);
+ GL_STREAM_DRAW);
buff->allocateBuffer(4, 12, TRUE);
face.setGeomIndex(0);
face.setIndicesIndex(0);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 98b2bc703b..862db08e62 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -60,6 +60,7 @@
#include "llfloatergridstatus.h"
#include "llfloaterimsession.h"
#include "lllocationhistory.h"
+#include "llgltfmateriallist.h"
#include "llimageworker.h"
#include "llloginflags.h"
@@ -97,6 +98,7 @@
#include "llfloateravatarpicker.h"
#include "llcallbacklist.h"
#include "llcallingcard.h"
+#include "llclassifiedinfo.h"
#include "llconsole.h"
#include "llcontainerview.h"
#include "llconversationlog.h"
@@ -124,8 +126,6 @@
#include "llpanellogin.h"
#include "llmutelist.h"
#include "llavatarpropertiesprocessor.h"
-#include "llpanelclassified.h"
-#include "llpanelpick.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
#include "llparcel.h"
@@ -194,6 +194,7 @@
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
#include "llpathfindingmanager.h"
+#include "llremoteparcelrequest.h"
#include "lllogin.h"
#include "llevents.h"
@@ -255,6 +256,7 @@ static bool mLoginStatePastUI = false;
static bool mBenefitsSuccessfullyInit = false;
const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds
+const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Give region 3 chances
std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
@@ -661,7 +663,7 @@ bool idle_startup()
#else
void* window_handle = NULL;
#endif
- bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle());
+ bool init = gAudiop->init(window_handle, LLAppViewer::instance()->getSecondLifeTitle());
if(init)
{
gAudiop->setMuted(TRUE);
@@ -927,6 +929,12 @@ bool idle_startup()
LLPersistentNotificationStorage::initParamSingleton();
LLDoNotDisturbNotificationStorage::initParamSingleton();
}
+ else
+ {
+ // reinitialize paths in case user switched grids or accounts
+ LLPersistentNotificationStorage::getInstance()->reset();
+ LLDoNotDisturbNotificationStorage::getInstance()->reset();
+ }
// Set PerAccountSettingsFile to the default value.
std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"));
@@ -1062,7 +1070,7 @@ bool idle_startup()
{
// Generic failure message
std::ostringstream emsg;
- emsg << LLTrans::getString("LoginFailed") << "\n";
+ emsg << LLTrans::getString("LoginFailedHeader") << "\n";
if(LLLoginInstance::getInstance()->authFailure())
{
LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
@@ -1075,11 +1083,37 @@ bool idle_startup()
std::string message_id = response["message_id"];
std::string message; // actual string to show the user
- if(!message_id.empty() && LLTrans::findString(message, message_id, response["message_args"]))
- {
- // message will be filled in with the template and arguments
- }
- else if(!message_response.empty())
+ bool localized_by_id = false;
+ if(!message_id.empty())
+ {
+ LLSD message_args = response["message_args"];
+ if (message_args.has("TIME")
+ && (message_id == "LoginFailedAcountSuspended"
+ || message_id == "LoginFailedAccountMaintenance"))
+ {
+ LLDate date;
+ std::string time_string;
+ if (date.fromString(message_args["TIME"].asString()))
+ {
+ LLSD args;
+ args["datetime"] = (S32)date.secondsSinceEpoch();
+ LLTrans::findString(time_string, "LocalTime", args);
+ }
+ else
+ {
+ time_string = message_args["TIME"].asString() + " " + LLTrans::getString("PacificTime");
+ }
+
+ message_args["TIME"] = time_string;
+ }
+ // message will be filled in with the template and arguments
+ if (LLTrans::findString(message, message_id, message_args))
+ {
+ localized_by_id = true;
+ }
+ }
+
+ if(!localized_by_id && !message_response.empty())
{
// *HACK: "no_inventory_host" sent as the message itself.
// Remove this clause when server is sending message_id as well.
@@ -1252,9 +1286,6 @@ bool idle_startup()
// Initialize classes w/graphics stuff.
//
LLViewerStatsRecorder::instance(); // Since textures work in threads
- gTextureList.doPrefetchImages();
- display_startup();
-
LLSurface::initClasses();
display_startup();
@@ -1362,10 +1393,21 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
}
+ else if (regionp->capabilitiesError())
+ {
+ // Try to connect despite capabilities' error state
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
else
{
U32 num_retries = regionp->getNumSeedCapRetries();
- if (num_retries > 0)
+ if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN)
+ {
+ // Region will keep trying to get capabilities,
+ // but for now continue as if caps were granted
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
+ else if (num_retries > 0)
{
LLStringUtil::format_map_t args;
args["[NUMBER]"] = llformat("%d", num_retries + 1);
@@ -1388,6 +1430,12 @@ bool idle_startup()
if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
{
display_startup();
+
+ // These textures are not warrantied to be cached, so needs
+ // to hapen with caps granted
+ gTextureList.doPrefetchImages();
+
+ display_startup();
update_texture_fetch();
display_startup();
@@ -1429,6 +1477,9 @@ bool idle_startup()
gXferManager->registerCallbacks(gMessageSystem);
display_startup();
+ LLGLTFMaterialList::registerCallbacks();
+ display_startup();
+
LLStartUp::initNameCache();
display_startup();
@@ -2359,6 +2410,11 @@ void login_callback(S32 option, void *userdata)
void show_release_notes_if_required()
{
static bool release_notes_shown = false;
+ // We happen to know that instantiating LLVersionInfo implicitly
+ // instantiates the LLEventMailDrop named "relnotes", which we (might) use
+ // below. If viewer release notes stop working, might be because that
+ // LLEventMailDrop got moved out of LLVersionInfo and hasn't yet been
+ // instantiated.
if (!release_notes_shown && (LLVersionInfo::instance().getChannelAndVersion() != gLastRunVersion)
&& LLVersionInfo::instance().getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds
&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
@@ -2477,8 +2533,6 @@ void use_circuit_callback(void**, S32 result)
void register_viewer_callbacks(LLMessageSystem* msg)
{
msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data );
- msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader );
- msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket );
msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update );
msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update );
msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update );
@@ -2626,7 +2680,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("EventInfoReply", LLEventNotifier::processEventInfoReply);
msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
-// msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);
msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);
msg->setHandlerFunc("ScriptDialog", process_script_dialog);
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index ea36e1d7be..1418499f8b 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -681,6 +681,13 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
}
}
}
+
+ if (did_update)
+ {
+ // some patches changed, update region reflection probes
+ mRegionp->updateReflectionProbes();
+ }
+
return did_update;
}
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 8f4eb9438b..8b79c7d911 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -987,7 +987,8 @@ void LLTextureCache::setReadOnly(BOOL read_only)
mReadOnly = read_only ;
}
-//called in the main thread.
+// Called in the main thread.
+// Returns the unused amount of max_size if any
S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch)
{
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 1c4a56b549..5d9eb48e6c 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -41,13 +41,17 @@
#include "llfolderviewmodel.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lllineeditor.h"
+#include "llmaterialeditor.h"
#include "llui.h"
#include "llviewerinventory.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llpermissions.h"
+#include "llpreviewtexture.h"
#include "llsaleinfo.h"
#include "llassetstorage.h"
#include "lltextbox.h"
@@ -69,16 +73,70 @@
#include "llradiogroup.h"
#include "llfloaterreg.h"
#include "lllocalbitmaps.h"
+#include "lllocalgltfmaterials.h"
#include "llerror.h"
#include "llavatarappearancedefines.h"
-static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
-
-//static const char CURRENT_IMAGE_NAME[] = "Current Texture";
-//static const char WHITE_IMAGE_NAME[] = "Blank Texture";
-//static const char NO_IMAGE_NAME[] = "None";
+//static
+bool get_is_predefined_texture(LLUUID asset_id)
+{
+ if (asset_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture"))
+ || asset_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID"))
+ || asset_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID"))
+ || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE))
+ {
+ return true;
+ }
+ return false;
+}
+
+LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id, bool no_trans_perm)
+{
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(asset_id);
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ LLUUID res;
+ if (items.size())
+ {
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLViewerInventoryItem* itemp = items[i];
+ if (itemp)
+ {
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ bool allow_trans = item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID());
+ if (allow_trans != no_trans_perm)
+ {
+ return itemp->getUUID();
+ }
+ res = itemp->getUUID();
+ }
+ }
+ }
+ }
+ return res;
+}
+
+bool get_can_copy_texture(LLUUID asset_id)
+{
+ // User is allowed to copy a texture if:
+ // library asset or default texture,
+ // or copy perm asset exists in user's inventory
+
+ return get_is_predefined_texture(asset_id) || get_copy_free_item_by_asset_id(asset_id).notNull();
+}
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLView* owner,
@@ -119,10 +177,11 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mOnFloaterCloseCallback(NULL),
mSetImageAssetIDCallback(NULL),
mOnUpdateImageStatsCallback(NULL),
- mBakeTextureEnabled(FALSE)
+ mBakeTextureEnabled(FALSE),
+ mInventoryPickType(LLTextureCtrl::PICK_TEXTURE)
{
- buildFromFile("floater_texture_ctrl.xml");
mCanApplyImmediately = can_apply_immediately;
+ buildFromFile("floater_texture_ctrl.xml");
setCanMinimize(FALSE);
}
@@ -193,10 +252,8 @@ void LLFloaterTexturePicker::setActive( BOOL active )
void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
{
mCanApplyImmediately = b;
- if (!mCanApplyImmediately)
- {
- getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
- }
+
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately);
updateFilterPermMask();
}
@@ -354,12 +411,8 @@ BOOL LLFloaterTexturePicker::postBuild()
childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
childSetAction("Blank", LLFloaterTexturePicker::onBtnBlank,this);
-
- childSetCommitCallback("show_folders_check", onShowFolders, this);
- getChildView("show_folders_check")->setVisible( FALSE);
-
- mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
- mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
+ mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
+ mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
@@ -369,12 +422,12 @@ BOOL LLFloaterTexturePicker::postBuild()
if(mInventoryPanel)
{
- U32 filter_types = 0x0;
- filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
- filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ // to avoid having to make an assumption about which option is
+ // selected at startup, we call the same function that is triggered
+ // when a texture/materials/both choice is made and let it take care
+ // of setting the filters
+ refreshInventoryFilter();
- mInventoryPanel->setFilterTypes(filter_types);
- //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
@@ -407,17 +460,13 @@ BOOL LLFloaterTexturePicker::postBuild()
mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list");
mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this);
- LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ refreshLocalList();
mNoCopyTextureSelected = FALSE;
getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
-
- if (!mCanApplyImmediately)
- {
- getChildView("show_folders_check")->setEnabled(FALSE);
- }
+ getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately);
getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
@@ -445,7 +494,6 @@ void LLFloaterTexturePicker::draw()
updateImageStats();
// if we're inactive, gray out "apply immediate" checkbox
- getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
getChildView("Select")->setEnabled(mActive && mCanApply);
getChildView("Pipette")->setEnabled(mActive);
getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
@@ -460,6 +508,8 @@ void LLFloaterTexturePicker::draw()
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
{
+ // TODO: Fix this! Picker is not warrantied to be connected to a selection
+ // LLSelectMgr shouldn't be used in texture picker
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
if (obj)
{
@@ -483,7 +533,7 @@ void LLFloaterTexturePicker::draw()
}
getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
- getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative);
+ getChildView("Blank")->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID != mDefaultImageAssetID) || mTentative);
getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
LLFloater::draw();
@@ -688,8 +738,18 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata)
{
if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty())
{
- LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
- local_id = LLLocalBitmapMgr::getInstance()->getWorldID(temp_id);
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID temp_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ local_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(temp_id);
+ }
+ else
+ {
+ local_id = LLLocalBitmapMgr::getInstance()->getWorldID(temp_id);
+ }
}
}
@@ -765,9 +825,6 @@ void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
self->getChild<LLFilterEditor>("inventory search editor")->setVisible(index == 0 ? TRUE : FALSE);
self->getChild<LLInventoryPanel>("inventory panel")->setVisible(index == 0 ? TRUE : FALSE);
- /*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode);
- no idea under which conditions the above is even shown, needs testing. */
-
self->getChild<LLButton>("l_add_btn")->setVisible(index == 1 ? TRUE : FALSE);
self->getChild<LLButton>("l_rem_btn")->setVisible(index == 1 ? TRUE : FALSE);
self->getChild<LLButton>("l_upl_btn")->setVisible(index == 1 ? TRUE : FALSE);
@@ -836,11 +893,20 @@ void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
// static
void LLFloaterTexturePicker::onBtnAdd(void* userdata)
{
- if (LLLocalBitmapMgr::getInstance()->addUnit() == true)
- {
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
- }
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
+
+ if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL_TEXTURE, true);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_IMAGE, true);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL, true);
+ }
}
// static
@@ -851,22 +917,32 @@ void LLFloaterTexturePicker::onBtnRemove(void* userdata)
if (!selected_items.empty())
{
+
for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin();
iter != selected_items.end(); iter++)
{
LLScrollListItem* list_item = *iter;
if (list_item)
{
- LLUUID tracking_id = list_item->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
- LLLocalBitmapMgr::getInstance()->delUnit(tracking_id);
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->delUnit(tracking_id);
+ }
+ else
+ {
+ LLLocalBitmapMgr::getInstance()->delUnit(tracking_id);
+ }
}
}
self->getChild<LLButton>("l_rem_btn")->setEnabled(false);
self->getChild<LLButton>("l_upl_btn")->setEnabled(false);
- LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ self->refreshLocalList();
}
-
}
// static
@@ -882,15 +958,29 @@ void LLFloaterTexturePicker::onBtnUpload(void* userdata)
/* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!)
in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */
-
- LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
- std::string filename = LLLocalBitmapMgr::getInstance()->getFilename(tracking_id);
-
- if (!filename.empty())
- {
- LLFloaterReg::showInstance("upload_image", LLSD(filename));
- }
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ std::string filename;
+ S32 index;
+ LLLocalGLTFMaterialMgr::getInstance()->getFilenameAndIndex(tracking_id, filename, index);
+ if (!filename.empty())
+ {
+ LLMaterialEditor::loadMaterialFromFile(filename, index);
+ }
+ }
+ else
+ {
+ std::string filename = LLLocalBitmapMgr::getInstance()->getFilename(tracking_id);
+ if (!filename.empty())
+ {
+ LLFloaterReg::showInstance("upload_image", LLSD(filename));
+ }
+ }
}
//static
@@ -906,8 +996,20 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
if (has_selection)
{
- LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
- LLUUID inworld_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+ LLUUID inworld_id;
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ inworld_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(tracking_id);
+ }
+ else
+ {
+ inworld_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
+ }
+
if (self->mSetImageAssetIDCallback)
{
self->mSetImageAssetIDCallback(inworld_id);
@@ -924,22 +1026,6 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
}
// static
-void LLFloaterTexturePicker::onShowFolders(LLUICtrl* ctrl, void *user_data)
-{
- LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
- LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
-
- if (check_box->get())
- {
- picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- }
- else
- {
- picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NO_FOLDERS);
- }
-}
-
-// static
void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_data)
{
LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
@@ -1081,6 +1167,48 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
mInventoryPanel->setFilterSubString(search_string);
}
+void LLFloaterTexturePicker::refreshLocalList()
+{
+ mLocalScrollCtrl->clearRows();
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+}
+
+void LLFloaterTexturePicker::refreshInventoryFilter()
+{
+ U32 filter_types = 0x0;
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ filter_types |= 0x1 << LLInventoryType::IT_MATERIAL;
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_MATERIAL;
+ }
+
+ mInventoryPanel->setFilterTypes(filter_types);
+}
+
void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
{
mModeSelector->setEnabledByValue(1, enabled);
@@ -1108,6 +1236,55 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled)
onModeSelect(0, this);
}
+void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryType type)
+{
+ mInventoryPickType = type;
+ refreshLocalList();
+ refreshInventoryFilter();
+}
+
+void LLFloaterTexturePicker::onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle)
+{
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty())
+ {
+ std::string temp_exten = gDirUtilp->getExtension(*iter);
+ if (temp_exten == "gltf" || temp_exten == "glb")
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->addUnit(*iter);
+ }
+ else
+ {
+ LLLocalBitmapMgr::getInstance()->addUnit(*iter);
+ }
+ }
+ iter++;
+ }
+
+ // Todo: this should referesh all pickers, not just a current one
+ if (!handle.isDead())
+ {
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)handle.get();
+ self->mLocalScrollCtrl->clearRows();
+
+ if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ }
+}
+
void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
{
LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
@@ -1146,7 +1323,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mOnCloseCallback(NULL),
mOnSelectCallback(NULL),
mBorderColor( p.border_color() ),
- mAllowNoTexture( FALSE ),
+ mAllowNoTexture( p.allow_no_texture ),
mAllowLocalTexture( TRUE ),
mImmediateFilterPermMask( PERM_NONE ),
mNonImmediateFilterPermMask( PERM_NONE ),
@@ -1154,6 +1331,9 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mNeedsRawImageData( FALSE ),
mValid( TRUE ),
mShowLoadingPlaceholder( TRUE ),
+ mOpenTexPreview(false),
+ mBakeTextureEnabled(true),
+ mInventoryPickType(PICK_TEXTURE),
mImageAssetID(p.image_id),
mDefaultImageAssetID(p.default_image_id),
mDefaultImageName(p.default_image_name),
@@ -1343,14 +1523,10 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
if (texture_floaterp)
{
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2));
- }
- if (texture_floaterp)
- {
texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
- }
- if (texture_floaterp)
- {
- texture_floaterp->setBakeTextureEnabled(TRUE);
+
+ texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled);
+ texture_floaterp->setInventoryPickType(mInventoryPickType);
}
LLFloater* root_floater = gFloaterView->getParentFloater(this);
@@ -1410,12 +1586,31 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
if (!handled && mBorder->parentPointInView(x, y))
{
- showPicker(FALSE);
- //grab textures first...
- LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
- //...then start full inventory fetch.
- LLInventoryModelBackgroundFetch::instance().start();
- handled = TRUE;
+ if (!mOpenTexPreview)
+ {
+ showPicker(FALSE);
+ //grab textures first...
+ LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
+ //...then start full inventory fetch.
+ LLInventoryModelBackgroundFetch::instance().start();
+ handled = TRUE;
+ }
+ else
+ {
+ if (getImageAssetID().notNull())
+ {
+ LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", getValue());
+ if (preview_texture && !preview_texture->isDependent())
+ {
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(preview_texture);
+ preview_texture->hideCtrlButtons();
+ }
+ }
+ }
+ }
}
return handled;
@@ -1439,9 +1634,9 @@ void LLTextureCtrl::onFloaterClose()
void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
{
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if( floaterp && getEnabled())
+ if( floaterp && getEnabled())
{
if (op == TEXTURE_CANCEL)
mViewModel->resetDirty();
@@ -1462,15 +1657,15 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
}
else
{
- mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
- LL_DEBUGS() << "mImageItemID: " << mImageItemID << LL_ENDL;
- mImageAssetID = floaterp->getAssetID();
- LL_DEBUGS() << "mImageAssetID: " << mImageAssetID << LL_ENDL;
+ mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
+ LL_DEBUGS() << "mImageItemID: " << mImageItemID << LL_ENDL;
+ mImageAssetID = floaterp->getAssetID();
+ LL_DEBUGS() << "mImageAssetID: " << mImageAssetID << LL_ENDL;
}
if (op == TEXTURE_SELECT && mOnSelectCallback)
{
- mOnSelectCallback( this, LLSD() );
+ mOnSelectCallback(this, LLSD());
}
else if (op == TEXTURE_CANCEL && mOnCancelCallback)
{
@@ -1481,8 +1676,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
// If the "no_commit_on_selection" parameter is set
// we commit only when user presses OK in the picker
// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
- if (mCommitOnSelection || op == TEXTURE_SELECT)
- onCommit();
+ if (mCommitOnSelection || op == TEXTURE_SELECT)
+ {
+ onCommit();
+ }
}
}
}
@@ -1527,8 +1724,9 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
}
}
-void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)
+void LLTextureCtrl::setBakeTextureEnabled(bool enabled)
{
+ mBakeTextureEnabled = enabled;
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if (floaterp)
{
@@ -1536,6 +1734,16 @@ void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)
}
}
+void LLTextureCtrl::setInventoryPickType(EPickInventoryType type)
+{
+ mInventoryPickType = type;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if (floaterp)
+ {
+ floaterp->setInventoryPickType(type);
+ }
+}
+
BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept,
@@ -1615,7 +1823,7 @@ void LLTextureCtrl::draw()
}
else//mImageAssetID == LLUUID::null
{
- mTexturep = NULL;
+ mTexturep = NULL;
}
// Border
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 92f6f89af6..0a5a281e76 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -52,6 +52,16 @@ class LLViewerFetchedTexture;
typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;
+// Helper functions for UI that work with picker
+bool get_is_predefined_texture(LLUUID asset_id);
+
+// texture picker works by asset ids since objects normaly do
+// not retain inventory ids as result these functions are looking
+// for textures in inventory by asset ids
+// This search can be performance unfriendly and doesn't warranty
+// that the texture is original source of asset
+LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false);
+bool get_can_copy_texture(LLUUID image_id);
//////////////////////////////////////////////////////////////////////////////////////////
// LLTextureCtrl
@@ -68,6 +78,13 @@ public:
TEXTURE_CANCEL
} ETexturePickOp;
+ typedef enum e_pick_inventory_type
+ {
+ PICK_TEXTURE_MATERIAL = 0,
+ PICK_TEXTURE = 1,
+ PICK_MATERIAL = 2,
+ } EPickInventoryType;
+
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
@@ -91,7 +108,7 @@ public:
: image_id("image"),
default_image_id("default_image_id"),
default_image_name("default_image_name"),
- allow_no_texture("allow_no_texture"),
+ allow_no_texture("allow_no_texture", false),
can_apply_immediately("can_apply_immediately"),
no_commit_on_selection("no_commit_on_selection", false),
label_width("label_width", -1),
@@ -159,6 +176,8 @@ public:
void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
+ void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; }
+
void setCaption(const std::string& caption);
void setCanApplyImmediately(BOOL b);
@@ -200,7 +219,11 @@ public:
LLViewerFetchedTexture* getTexture() { return mTexturep; }
- void setBakeTextureEnabled(BOOL enabled);
+ void setBakeTextureEnabled(bool enabled);
+ bool getBakeTextureEnabled() const { return mBakeTextureEnabled; }
+
+ void setInventoryPickType(EPickInventoryType type);
+ EPickInventoryType getInventoryPickType() { return mInventoryPickType; };
private:
BOOL allowDrop(LLInventoryItem* item);
@@ -238,6 +261,9 @@ private:
BOOL mShowLoadingPlaceholder;
std::string mLoadingPlaceholderString;
S32 mLabelWidth;
+ bool mOpenTexPreview;
+ bool mBakeTextureEnabled;
+ LLTextureCtrl::EPickInventoryType mInventoryPickType;
};
//////////////////////////////////////////////////////////////////////////////////////////
@@ -315,9 +341,7 @@ public:
//static void onBtnRevert( void* userdata );
static void onBtnBlank(void* userdata);
static void onBtnNone(void* userdata);
- static void onBtnClear(void* userdata);
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
- static void onShowFolders(LLUICtrl* ctrl, void* userdata);
static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
void onTextureSelect(const LLTextureEntry& te);
@@ -333,7 +357,14 @@ public:
void setLocalTextureEnabled(BOOL enabled);
void setBakeTextureEnabled(BOOL enabled);
+ void setInventoryPickType(LLTextureCtrl::EPickInventoryType type);
+
+ static void onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle);
+
protected:
+ void refreshLocalList();
+ void refreshInventoryFilter();
+
LLPointer<LLViewerTexture> mTexturep;
LLView* mOwner;
@@ -372,6 +403,7 @@ private:
bool mCanApply;
bool mCanPreview;
bool mPreviewSettingChanged;
+ LLTextureCtrl::EPickInventoryType mInventoryPickType;
texture_selected_callback mTextureSelectedCallback;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 604444b64a..7cccd6f5ac 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -262,7 +262,6 @@ static const char* e_state_name[] =
"LOAD_FROM_TEXTURE_CACHE",
"CACHE_POST",
"LOAD_FROM_NETWORK",
- "LOAD_FROM_SIMULATOR",
"WAIT_HTTP_RESOURCE",
"WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
@@ -428,7 +427,6 @@ public:
LOAD_FROM_TEXTURE_CACHE,
CACHE_POST,
LOAD_FROM_NETWORK,
- LOAD_FROM_SIMULATOR,
WAIT_HTTP_RESOURCE, // Waiting for HTTP resources
WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources
SEND_HTTP_REQ, // Commit to sending as HTTP
@@ -472,17 +470,11 @@ private:
// Locks: Mw
void clearPackets();
- // Locks: Mw
- void setupPacketData();
// Locks: Mw
void removeFromCache();
// Threads: Ttf
- // Locks: Mw
- bool processSimulatorPackets();
-
- // Threads: Ttf
bool writeToCacheComplete();
// Threads: Ttf
@@ -581,8 +573,7 @@ private:
BOOL mHaveAllData;
BOOL mInLocalCache;
BOOL mInCache;
- bool mCanUseHTTP,
- mCanUseNET ; //can get from asset server.
+ bool mCanUseHTTP;
S32 mRetryAttempt;
S32 mActiveCount;
LLCore::HttpStatus mGetStatus;
@@ -854,7 +845,6 @@ const char* sStateDescs[] = {
"LOAD_FROM_TEXTURE_CACHE",
"CACHE_POST",
"LOAD_FROM_NETWORK",
- "LOAD_FROM_SIMULATOR",
"WAIT_HTTP_RESOURCE",
"WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
@@ -866,7 +856,7 @@ const char* sStateDescs[] = {
"DONE"
};
-const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR,
+const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK,
LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE };
// static
@@ -940,8 +930,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mResourceWaitCount(0U),
mFetchRetryPolicy(10.f,3600.f,2.f,10)
{
- mCanUseNET = mUrl.empty() ;
-
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
if (!mFetcher->mDebugPause)
@@ -1003,39 +991,6 @@ void LLTextureFetchWorker::clearPackets()
mFirstPacket = 0;
}
-// Locks: Mw
-void LLTextureFetchWorker::setupPacketData()
-{
- S32 data_size = 0;
- if (mFormattedImage.notNull())
- {
- data_size = mFormattedImage->getDataSize();
- }
- if (data_size > 0)
- {
- // Only used for simulator requests
- mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1;
- if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size)
- {
- LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL;
- removeFromCache();
- resetFormattedData();
- clearPackets();
- }
- else if (mFileSize > 0)
- {
- mLastPacket = mFirstPacket-1;
- mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1;
- }
- else
- {
- // This file was cached using HTTP so we have to refetch the first packet
- resetFormattedData();
- clearPackets();
- }
- }
-}
-
// Locks: Mw (ctor invokes without lock)
void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
{
@@ -1127,14 +1082,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mImagePriority < F_ALMOST_ZERO)
{
- if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
+ if (mState == INIT || mState == LOAD_FROM_NETWORK)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - priority < 0");
LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
return true; // abort
}
}
- if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
+ if(mState > CACHE_POST && !mCanUseHTTP)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post");
//nowhere to get data, abort.
@@ -1336,10 +1291,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
LLViewerRegion* region = NULL;
- if (mHost.isInvalid())
- region = gAgent.getRegion();
- else
- region = LLWorld::getInstance()->getRegion(mHost);
+ if (mHost.isInvalid())
+ {
+ region = gAgent.getRegion();
+ }
+ else if (LLWorld::instanceExists())
+ {
+ region = LLWorld::getInstance()->getRegion(mHost);
+ }
if (region)
{
@@ -1357,14 +1316,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
else
{
mCanUseHTTP = false ;
- LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
+ LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
}
}
else
{
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
- LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
+ LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
mCanUseHTTP = false;
}
}
@@ -1382,77 +1341,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
// don't return, fall through to next state
}
- else if (mSentRequest == UNSENT && mCanUseNET)
- {
- // Add this to the network queue and sit here.
- // LLTextureFetch::update() will send off a request which will change our state
- mWriteToCacheState = CAN_WRITE ;
- mRequestedSize = mDesiredSize;
- mRequestedDiscard = mDesiredDiscard;
- mSentRequest = QUEUED;
- mFetcher->addToNetworkQueue(this);
- recordTextureStart(false);
- return false;
- }
else
{
- // Shouldn't need to do anything here
- //llassert(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
return false;
}
}
- if (mState == LOAD_FROM_SIMULATOR)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_SIMULATOR");
- if (mFormattedImage.isNull())
- {
- mFormattedImage = new LLImageJ2C;
- }
- if (processSimulatorPackets())
- {
- // Capture some measure of total size for metrics
- F64 byte_count = 0;
- if (mLastPacket >= mFirstPacket)
- {
- for (S32 i=mFirstPacket; i<=mLastPacket; i++)
- {
- llassert_always((i>=0) && (i<mPackets.size()));
- if (mPackets[i])
- {
- byte_count += mPackets[i]->mSize;
- }
- }
- }
-
- LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL;
- mFetcher->removeFromNetworkQueue(this, false);
- if (mFormattedImage.isNull() || !mFormattedImage->getDataSize())
- {
- // processSimulatorPackets() failed
-// LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL;
- LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL;
- return true; // failed
- }
-
- if (mLoadedDiscard < 0)
- {
- LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
- << ", should be >=0" << LL_ENDL;
- }
- setState(DECODE_IMAGE);
- mWriteToCacheState = SHOULD_WRITE;
-
- recordTextureDone(false, byte_count);
- }
- else
- {
- mFetcher->addToNetworkQueue(this); // failsafe
- recordTextureStart(false);
- }
- return false;
- }
-
if (mState == WAIT_HTTP_RESOURCE)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE");
@@ -1496,8 +1390,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL;
return true; // abort
}
-
- mFetcher->removeFromNetworkQueue(this, false);
S32 cur_size = 0;
if (mFormattedImage.notNull())
@@ -1642,17 +1534,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return true;
}
-
- // roll back to try UDP
- if (mCanUseNET)
- {
- setState(INIT);
- mCanUseHTTP = false;
- mUrl.clear();
- releaseHttpSemaphore();
- //return false;
- return doWork(param);
- }
}
else if (http_service_unavail == mGetStatus)
{
@@ -1868,7 +1749,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
setState(DECODE_IMAGE_UPDATE);
LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
<< " All Data: " << mHaveAllData << LL_ENDL;
- mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, discard, mNeedsAux,
+ mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, discard, mNeedsAux,
new DecodeResponder(mFetcher, mID, this));
// fall though
}
@@ -2222,69 +2103,6 @@ void LLTextureFetchWorker::removeFromCache()
// Threads: Ttf
// Locks: Mw
-bool LLTextureFetchWorker::processSimulatorPackets()
-{
- if (mFormattedImage.isNull() || mRequestedSize < 0)
- {
- // not sure how we got here, but not a valid state, abort!
- llassert_always(mDecodeHandle == 0);
- mFormattedImage = NULL;
- return true;
- }
-
- if (mLastPacket >= mFirstPacket)
- {
- S32 buffer_size = mFormattedImage->getDataSize();
- for (S32 i = mFirstPacket; i<=mLastPacket; i++)
- {
- llassert_always((i>=0) && (i<mPackets.size()));
- llassert_always(mPackets[i]);
- buffer_size += mPackets[i]->mSize;
- }
- bool have_all_data = mLastPacket >= mTotalPackets-1;
- if (mRequestedSize <= 0)
- {
- // We received a packed but haven't requested anything yet (edge case)
- // Return true (we're "done") since we didn't request anything
- return true;
- }
- if (buffer_size >= mRequestedSize || have_all_data)
- {
- /// We have enough (or all) data
- if (have_all_data)
- {
- mHaveAllData = TRUE;
- }
- S32 cur_size = mFormattedImage->getDataSize();
- if (buffer_size > cur_size)
- {
- /// We have new data
- U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size);
- S32 offset = 0;
- if (cur_size > 0 && mFirstPacket > 0)
- {
- memcpy(buffer, mFormattedImage->getData(), cur_size);
- offset = cur_size;
- }
- for (S32 i=mFirstPacket; i<=mLastPacket; i++)
- {
- memcpy(buffer + offset, mPackets[i]->mData, mPackets[i]->mSize);
- offset += mPackets[i]->mSize;
- }
- // NOTE: setData releases current data
- mFormattedImage->setData(buffer, buffer_size);
- }
- mLoadedDiscard = mRequestedDiscard;
- return true;
- }
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-// Threads: Ttf
-// Locks: Mw
S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
bool partial, bool success)
{
@@ -2540,7 +2358,7 @@ std::string LLTextureFetch::getStateString(S32 state)
return e_state_name[state];
}
-LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode)
+LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode)
: LLWorkerThread("TextureFetch", threaded, true),
mDebugCount(0),
mDebugPause(FALSE),
@@ -2549,7 +2367,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mQueueMutex(),
mNetworkQueueMutex(),
mTextureCache(cache),
- mImageDecodeThread(imagedecodethread),
mTextureBandwidth(0),
mHTTPTextureBits(0),
mTotalHTTPRequests(0),
@@ -2617,13 +2434,13 @@ LLTextureFetch::~LLTextureFetch()
// ~LLQueuedThread() called here
}
-bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
{
LL_PROFILE_ZONE_SCOPED;
if (mDebugPause)
{
- return false;
+ return -1;
}
if (f_type == FTT_SERVER_BAKE)
@@ -2639,7 +2456,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
<< host << " != " << worker->mHost << LL_ENDL;
removeRequest(worker, true);
worker = NULL;
- return false;
+ return -1;
}
}
@@ -2692,13 +2509,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
{
if (worker->wasAborted())
{
- return false; // need to wait for previous aborted request to complete
+ return -1; // need to wait for previous aborted request to complete
}
worker->lockWorkMutex(); // +Mw
if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) {
worker->unlockWorkMutex(); // -Mw
- return false; // similar request has failed or is in a transitional state
+ return -1; // similar request has failed or is in a transitional state
}
worker->mActiveCount++;
worker->mNeedsAux = needs_aux;
@@ -2733,49 +2550,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
worker->setCanUseHTTP(can_use_http) ;
worker->unlockWorkMutex(); // -Mw
}
-
+
LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type)
<< " Discard: " << desired_discard << " size " << desired_size << LL_ENDL;
- return true;
+ return desired_discard;
}
-// Threads: T* (but Ttf in practice)
-
-// protected
-void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
-{
- LL_PROFILE_ZONE_SCOPED;
- lockQueue(); // +Mfq
- bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ;
- unlockQueue(); // -Mfq
-
- LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
- if (in_request_map)
- {
- // only add to the queue if in the request map
- // i.e. a delete has not been requested
- mNetworkQueue.insert(worker->mID);
- }
- for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
- iter1 != mCancelQueue.end(); ++iter1)
- {
- iter1->second.erase(worker->mID);
- }
-} // -Mfnq
-
-// Threads: T*
-void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel)
-{
- LL_PROFILE_ZONE_SCOPED;
- LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
- size_t erased = mNetworkQueue.erase(worker->mID);
- if (cancel && erased > 0)
- {
- mCancelQueue[worker->mHost].insert(worker->mID);
- }
-} // -Mfnq
-
// Threads: T*
//
// protected
@@ -2812,7 +2593,6 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
- removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
worker->scheduleDelete();
@@ -2841,7 +2621,6 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
- removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
worker->scheduleDelete();
@@ -3138,17 +2917,6 @@ S32 LLTextureFetch::update(F32 max_time_ms)
S32 res = LLWorkerThread::update(max_time_ms);
- if (!mDebugPause)
- {
- // this is the startup state when send_complete_agent_movement() message is sent.
- // Before this, the RequestImages message sent by sendRequestListToSimulators
- // won't work so don't bother trying
- if (LLStartUp::getStartupState() > STATE_AGENT_SEND)
- {
- sendRequestListToSimulators();
- }
- }
-
if (!mThreaded)
{
commonUpdate();
@@ -3169,18 +2937,6 @@ void LLTextureFetch::shutDownTextureCacheThread()
}
}
-// called in the MAIN thread after the ImageDecodeThread shuts down.
-//
-// Threads: Tmain
-void LLTextureFetch::shutDownImageDecodeThread()
-{
- if(mImageDecodeThread)
- {
- delete mImageDecodeThread;
- mImageDecodeThread = NULL ;
- }
-}
-
// Threads: Ttf
void LLTextureFetch::startThread()
{
@@ -3235,202 +2991,6 @@ void LLTextureFetch::threadedUpdate()
//////////////////////////////////////////////////////////////////////////////
-// Threads: Tmain
-void LLTextureFetch::sendRequestListToSimulators()
-{
- LL_PROFILE_ZONE_SCOPED;
- // All requests
- const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps
-
- // Sim requests
- const S32 IMAGES_PER_REQUEST = 50;
- const F32 SIM_LAZY_FLUSH_TIMEOUT = 10.0f; // temp
- const F32 MIN_REQUEST_TIME = 1.0f;
- const F32 MIN_DELTA_PRIORITY = 1000.f;
-
- // Periodically, gather the list of textures that need data from the network
- // And send the requests out to the simulators
- static LLFrameTimer timer;
- if (timer.getElapsedTimeF32() < REQUEST_DELTA_TIME)
- {
- return;
- }
- timer.reset();
-
- // Send requests
- typedef std::set<LLTextureFetchWorker*,LLTextureFetchWorker::Compare> request_list_t;
- typedef std::map< LLHost, request_list_t > work_request_map_t;
- work_request_map_t requests;
- {
- LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
- for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
- {
- queue_t::iterator curiter = iter++;
- LLTextureFetchWorker* req = getWorker(*curiter);
- if (!req)
- {
- mNetworkQueue.erase(curiter);
- continue; // paranoia
- }
- if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) &&
- (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR))
- {
- // We already received our URL, remove from the queue
- LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL;
- mNetworkQueue.erase(curiter);
- continue;
- }
- if (req->mID == mDebugID)
- {
- mDebugCount++; // for setting breakpoints
- }
- if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM &&
- req->mTotalPackets > 0 &&
- req->mLastPacket >= req->mTotalPackets-1)
- {
- // We have all the packets... make sure this is high priority
- continue;
- }
- F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32();
- {
- F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
- if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
- (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
- (elapsed >= SIM_LAZY_FLUSH_TIMEOUT))
- {
- requests[req->mHost].insert(req);
- }
- }
- }
- } // -Mfnq
-
- for (work_request_map_t::iterator iter1 = requests.begin();
- iter1 != requests.end(); ++iter1)
- {
- LLHost host = iter1->first;
- // invalid host = use agent host
- if (host.isInvalid())
- {
- host = gAgent.getRegionHost();
- }
-
- S32 sim_request_count = 0;
-
- for (request_list_t::iterator iter2 = iter1->second.begin();
- iter2 != iter1->second.end(); ++iter2)
- {
- LLTextureFetchWorker* req = *iter2;
- if (gMessageSystem)
- {
- if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM)
- {
- // Initialize packet data based on data read from cache
- req->lockWorkMutex(); // +Mw
- req->setupPacketData();
- req->unlockWorkMutex(); // -Mw
- }
- if (0 == sim_request_count)
- {
- gMessageSystem->newMessageFast(_PREHASH_RequestImage);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- }
- S32 packet = req->mLastPacket + 1;
- gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
- gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
- gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard);
- gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority);
- gMessageSystem->addU32Fast(_PREHASH_Packet, packet);
- gMessageSystem->addU8Fast(_PREHASH_Type, req->mType);
-// LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
-// << " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL;
-
- static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
- static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
- if (log_to_viewer_log || log_to_sim)
- {
- mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime());
- mTextureInfo.setRequestOffset(req->mID, 0);
- mTextureInfo.setRequestSize(req->mID, 0);
- mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP);
- }
-
- req->lockWorkMutex(); // +Mw
- req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
- req->mSimRequestedDiscard = req->mDesiredDiscard;
- req->mRequestedPriority = req->mImagePriority;
- req->mRequestedDeltaTimer.reset();
- req->unlockWorkMutex(); // -Mw
- sim_request_count++;
- if (sim_request_count >= IMAGES_PER_REQUEST)
- {
-// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
-
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- sim_request_count = 0;
- }
- }
- }
- if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST)
- {
-// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- sim_request_count = 0;
- }
- }
-
- // Send cancelations
- {
- LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
- if (gMessageSystem && !mCancelQueue.empty())
- {
- for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
- iter1 != mCancelQueue.end(); ++iter1)
- {
- LLHost host = iter1->first;
- if (host.isInvalid())
- {
- host = gAgent.getRegionHost();
- }
- S32 request_count = 0;
- for (queue_t::iterator iter2 = iter1->second.begin();
- iter2 != iter1->second.end(); ++iter2)
- {
- if (0 == request_count)
- {
- gMessageSystem->newMessageFast(_PREHASH_RequestImage);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- }
- gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
- gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2);
- gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1);
- gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0);
- gMessageSystem->addU32Fast(_PREHASH_Packet, 0);
- gMessageSystem->addU8Fast(_PREHASH_Type, 0);
-// LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL;
-
- request_count++;
- if (request_count >= IMAGES_PER_REQUEST)
- {
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- request_count = 0;
- }
- }
- if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
- {
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- }
- }
- mCancelQueue.clear();
- }
- } // -Mfnq
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
// Threads: T*
// Locks: Mw
bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
@@ -3495,138 +3055,6 @@ void LLTextureFetchWorker::setState(e_state new_state)
mState = new_state;
}
-// Threads: T*
-bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
- U16 data_size, U8* data)
-{
- LL_PROFILE_ZONE_SCOPED;
- LLTextureFetchWorker* worker = getWorker(id);
- bool res = true;
-
- ++mPacketCount;
-
- if (!worker)
- {
-// LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL;
- res = false;
- }
- else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK ||
- worker->mSentRequest != LLTextureFetchWorker::SENT_SIM)
- {
-// LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id
-// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState]
-// << " sent: " << worker->mSentRequest << LL_ENDL;
- res = false;
- }
- else if (worker->mLastPacket != -1)
- {
- // check to see if we've gotten this packet before
-// LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL;
- res = false;
- }
- else if (!data_size)
- {
-// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
- res = false;
- }
- if (!res)
- {
- mNetworkQueueMutex.lock(); // +Mfnq
- ++mBadPacketCount;
- mCancelQueue[host].insert(id);
- mNetworkQueueMutex.unlock(); // -Mfnq
- return false;
- }
-
- LLViewerStatsRecorder::instance().textureFetch(data_size);
- LLViewerStatsRecorder::instance().log(0.1f);
-
- worker->lockWorkMutex();
-
-
- // Copy header data into image object
- worker->mImageCodec = codec;
- worker->mTotalPackets = packets;
- worker->mFileSize = (S32)totalbytes;
- llassert_always(totalbytes > 0);
- llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
- res = worker->insertPacket(0, data, data_size);
- worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
- worker->unlockWorkMutex(); // -Mw
- return res;
-}
-
-
-// Threads: T*
-bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
-{
- LL_PROFILE_ZONE_SCOPED;
- LLTextureFetchWorker* worker = getWorker(id);
- bool res = true;
-
- ++mPacketCount;
-
- if (!worker)
- {
-// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL;
- res = false;
- }
- else if (worker->mLastPacket == -1)
- {
-// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL;
- res = false;
- }
- else if (!data_size)
- {
-// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
- res = false;
- }
- if (!res)
- {
- mNetworkQueueMutex.lock(); // +Mfnq
- ++mBadPacketCount;
- mCancelQueue[host].insert(id);
- mNetworkQueueMutex.unlock(); // -Mfnq
- return false;
- }
-
- LLViewerStatsRecorder::instance().textureFetch(data_size);
- LLViewerStatsRecorder::instance().log(0.1f);
-
- worker->lockWorkMutex();
-
-
- res = worker->insertPacket(packet_num, data, data_size);
-
- if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) ||
- (worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
- {
- worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
- }
- else
- {
-// LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id
-// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL;
- removeFromNetworkQueue(worker, true); // failsafe
- }
-
- if (packet_num >= (worker->mTotalPackets - 1))
- {
- static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
- static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
-
- if (log_to_viewer_log || log_to_sim)
- {
- U64Microseconds timeNow = LLTimer::getTotalTime();
- mTextureInfoMainThread.setRequestSize(id, worker->mFileSize);
- mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow);
- }
- }
- worker->unlockWorkMutex(); // -Mw
-
- return res;
-}
-
//////////////////////////////////////////////////////////////////////////////
// Threads: T*
@@ -3678,13 +3106,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32();
if (worker->mFileSize > 0)
{
- if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR)
- {
- S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE;
- data_size = llmax(data_size, 0);
- data_progress = (F32)data_size / (F32)worker->mFileSize;
- }
- else if (worker->mFormattedImage.notNull())
+ if (worker->mFormattedImage.notNull())
{
data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize;
}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 320511f343..4297117f75 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -60,7 +60,7 @@ class LLTextureFetch : public LLWorkerThread
public:
static std::string getStateString(S32 state);
- LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode);
+ LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode);
~LLTextureFetch();
class TFRequest;
@@ -77,7 +77,7 @@ public:
void shutDownImageDecodeThread();
// Threads: T* (but Tmain mostly)
- bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+ S32 createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
// Requests that a fetch operation be deleted from the queue.
@@ -102,12 +102,6 @@ public:
// Threads: T*
bool updateRequestPriority(const LLUUID& id, F32 priority);
- // Threads: T*
- bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
-
- // Threads: T*
- bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
-
// Threads: T* (but not safe)
void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
@@ -229,12 +223,6 @@ public:
// ----------------------------------
protected:
- // Threads: T* (but Ttf in practice)
- void addToNetworkQueue(LLTextureFetchWorker* worker);
-
- // Threads: T*
- void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
-
// Threads: T*
void addToHTTPQueue(const LLUUID& id);
@@ -253,9 +241,6 @@ protected:
bool runCondition();
private:
- // Threads: Tmain
- void sendRequestListToSimulators();
-
// Threads: Ttf
/*virtual*/ void startThread(void);
@@ -321,10 +306,9 @@ public:
private:
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
- LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
+ LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue
LLTextureCache* mTextureCache;
- LLImageDecodeThread* mImageDecodeThread;
// Map of all requests by UUID
typedef std::map<LLUUID,LLTextureFetchWorker*> map_t;
@@ -332,10 +316,8 @@ private:
// Set of requests that require network data
typedef std::set<LLUUID> queue_t;
- queue_t mNetworkQueue; // Mfnq
queue_t mHTTPTextureQueue; // Mfnq
typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
- cancel_queue_t mCancelQueue; // Mfnq
F32 mTextureBandwidth; // <none>
F32 mMaxBandwidth; // Mfnq
LLTextureInfo mTextureInfo;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index f0e9cee101..1f4f086352 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -223,7 +223,6 @@ void LLTextureBar::draw()
{ "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE
{ "DSK", LLColor4::blue }, // CACHE_POST
{ "NET", LLColor4::green }, // LOAD_FROM_NETWORK
- { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2
{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ
diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp
new file mode 100644
index 0000000000..c80e87652a
--- /dev/null
+++ b/indra/newview/lltinygltfhelper.cpp
@@ -0,0 +1,183 @@
+/**
+ * @file lltinygltfhelper.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltinygltfhelper.h"
+
+#include "llimage.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+void strip_alpha_channel(LLPointer<LLImageRaw>& img)
+{
+ if (img->getComponents() == 4)
+ {
+ LLImageRaw* tmp = new LLImageRaw(img->getWidth(), img->getHeight(), 3);
+ tmp->copyUnscaled4onto3(img);
+ img = tmp;
+ }
+}
+
+// copy red channel from src_img to dst_img
+// PRECONDITIONS:
+// dst_img must be 3 component
+// src_img and dst_image must have the same dimensions
+void copy_red_channel(LLPointer<LLImageRaw>& src_img, LLPointer<LLImageRaw>& dst_img)
+{
+ llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight());
+ llassert(dst_img->getComponents() == 3);
+
+ U32 pixel_count = dst_img->getWidth() * dst_img->getHeight();
+ U8* src = src_img->getData();
+ U8* dst = dst_img->getData();
+ S8 src_components = src_img->getComponents();
+
+ for (U32 i = 0; i < pixel_count; ++i)
+ {
+ dst[i * 3] = src[i * src_components];
+ }
+}
+
+void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material,
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLViewerFetchedTexture>& base_color_tex,
+ LLPointer<LLViewerFetchedTexture>& normal_tex,
+ LLPointer<LLViewerFetchedTexture>& mr_tex,
+ LLPointer<LLViewerFetchedTexture>& emissive_tex)
+{
+ if (base_color_img)
+ {
+ base_color_tex = LLViewerTextureManager::getFetchedTexture(base_color_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (normal_img)
+ {
+ strip_alpha_channel(normal_img);
+ normal_tex = LLViewerTextureManager::getFetchedTexture(normal_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (mr_img)
+ {
+ strip_alpha_channel(mr_img);
+
+ if (occlusion_img && material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index)
+ {
+ // occlusion is a distinct texture from pbrMetallicRoughness
+ // pack into mr red channel
+ int occlusion_idx = material.occlusionTexture.index;
+ int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (occlusion_idx != mr_idx)
+ {
+ //scale occlusion image to match resolution of mr image
+ occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight());
+
+ copy_red_channel(occlusion_img, mr_img);
+ }
+ }
+ }
+ else if (occlusion_img)
+ {
+ //no mr but occlusion exists, make a white mr_img and copy occlusion red channel over
+ mr_img = new LLImageRaw(occlusion_img->getWidth(), occlusion_img->getHeight(), 3);
+ mr_img->clear(255, 255, 255);
+ copy_red_channel(occlusion_img, mr_img);
+ }
+
+ if (mr_img)
+ {
+ mr_tex = LLViewerTextureManager::getFetchedTexture(mr_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (emissive_img)
+ {
+ strip_alpha_channel(emissive_img);
+ emissive_tex = LLViewerTextureManager::getFetchedTexture(emissive_img, FTType::FTT_LOCAL_FILE, true);
+ }
+}
+
+LLColor4 LLTinyGLTFHelper::getColor(const std::vector<double>& in)
+{
+ LLColor4 out;
+ for (S32 i = 0; i < llmin((S32)in.size(), 4); ++i)
+ {
+ out.mV[i] = in[i];
+ }
+
+ return out;
+}
+
+const tinygltf::Image * LLTinyGLTFHelper::getImageFromTextureIndex(const tinygltf::Model & model, S32 texture_index)
+{
+ if (texture_index >= 0)
+ {
+ S32 source_idx = model.textures[texture_index].source;
+ if (source_idx >= 0)
+ {
+ return &(model.images[source_idx]);
+ }
+ }
+
+ return nullptr;
+}
+
+LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index, std::string & name)
+{
+ const tinygltf::Image* image = getImageFromTextureIndex(model, texture_index);
+ LLImageRaw* rawImage = nullptr;
+
+ if (image != nullptr &&
+ image->bits == 8 &&
+ !image->image.empty() &&
+ image->component <= 4)
+ {
+ name = image->name;
+ rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
+ rawImage->verticalFlip();
+ }
+
+ return rawImage;
+}
+
+LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index)
+{
+ const tinygltf::Image* image = getImageFromTextureIndex(model, texture_index);
+ LLImageRaw* rawImage = nullptr;
+
+ if (image != nullptr &&
+ image->bits == 8 &&
+ !image->image.empty() &&
+ image->component <= 4)
+ {
+ rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
+ rawImage->verticalFlip();
+ }
+
+ return rawImage;
+}
diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h
new file mode 100644
index 0000000000..9c2e5afc17
--- /dev/null
+++ b/indra/newview/lltinygltfhelper.h
@@ -0,0 +1,54 @@
+/**
+ * @file lltinygltfhelper.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+
+#pragma once
+
+#include "llgltfmaterial.h"
+#include "llpointer.h"
+#include "tinygltf/tiny_gltf.h"
+
+class LLImageRaw;
+class LLViewerFetchedTexture;
+
+namespace LLTinyGLTFHelper
+{
+ LLColor4 getColor(const std::vector<double>& in);
+ const tinygltf::Image* getImageFromTextureIndex(const tinygltf::Model& model, S32 texture_index);
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name);
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index);
+
+ void initFetchedTextures(tinygltf::Material& material,
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLViewerFetchedTexture>& base_color_tex,
+ LLPointer<LLViewerFetchedTexture>& normal_tex,
+ LLPointer<LLViewerFetchedTexture>& mr_tex,
+ LLPointer<LLViewerFetchedTexture>& emissive_tex);
+}
+
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 8baad30e8f..692e8d91a9 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -291,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLineEditor->setText(edit_text_contents);
std::string notif_name = mNotification->getName();
- if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))
+ if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name) || ("CreateSubfolder" == notif_name))
{
mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 50868d0fa5..3f45d4f0da 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -60,6 +60,7 @@
#include "llvoavatarself.h"
#include "llworld.h"
#include "llpanelface.h"
+#include "lluiusage.h"
// syntactic sugar
#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
@@ -256,7 +257,8 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
// |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------|
addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_MATERIAL, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMaterialObject, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL));
@@ -271,6 +273,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SETTINGS, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+
// TODO: animation on self could play it? edit it?
// TODO: gesture on self could play it? edit it?
};
@@ -921,17 +924,17 @@ void LLToolDragAndDrop::pick(const LLPickInfo& pick_info)
}
// static
-BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
+BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id)
{
// Always succeed if....
- // texture is from the library
+ // material is from the library
// or already in the contents of the object
if (SOURCE_LIBRARY == source)
{
- // dropping a texture from the library always just works.
+ // dropping a material from the library always just works.
return TRUE;
}
@@ -962,15 +965,15 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
- // Check that we can add the texture as inventory to the object
+ // Check that we can add the material as inventory to the object
if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
{
return FALSE;
}
- // make sure the object has the texture in it's inventory.
+ // make sure the object has the material in it's inventory.
if (SOURCE_AGENT == source)
{
- // Remove the texture from local inventory. The server
+ // Remove the material from local inventory. The server
// will actually remove the item from agent inventory.
gInventory.deleteObject(item->getUUID());
gInventory.notifyObservers();
@@ -992,10 +995,11 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
}
}
// Add the texture item to the target object's inventory.
- if (LLAssetType::AT_TEXTURE == new_item->getType())
- {
- hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- }
+ if (LLAssetType::AT_TEXTURE == new_item->getType()
+ || LLAssetType::AT_MATERIAL == new_item->getType())
+ {
+ hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
else
{
hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
@@ -1014,9 +1018,10 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
// *FIX: may want to make sure agent can paint hit_obj.
// Add the texture item to the target object's inventory.
- if (LLAssetType::AT_TEXTURE == new_item->getType())
+ if (LLAssetType::AT_TEXTURE == new_item->getType()
+ || LLAssetType::AT_MATERIAL == new_item->getType())
{
- hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
}
else
{
@@ -1043,7 +1048,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
return;
}
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
@@ -1062,6 +1067,59 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
hit_obj->sendTEUpdate();
}
+
+void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
+ S32 hit_face,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ if (hit_face == -1) return;
+ if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL;
+ return;
+ }
+ LLUUID asset_id = item->getAssetUUID();
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+ if (!success)
+ {
+ return;
+ }
+
+ hit_obj->setRenderMaterialID(hit_face, asset_id);
+
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ hit_obj->sendTEUpdate();
+}
+
+
+void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL;
+ return;
+ }
+ LLUUID asset_id = item->getAssetUUID();
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+ if (!success)
+ {
+ return;
+ }
+
+ hit_obj->setRenderMaterialIDs(asset_id);
+ dialog_refresh_all();
+ // send the update to the simulator
+ hit_obj->sendTEUpdate();
+}
+
+
void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
@@ -1073,7 +1131,7 @@ void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
return;
}
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if(!success)
{
return;
@@ -1100,7 +1158,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
S32 hit_face,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
- const LLUUID& src_id)
+ const LLUUID& src_id,
+ S32 tex_channel)
{
if (hit_face == -1) return;
if (!item)
@@ -1109,7 +1168,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
return;
}
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
@@ -1124,7 +1183,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
if (gFloaterTools->getVisible() && panel_face)
{
- switch (LLSelectMgr::getInstance()->getTextureChannel())
+ tex_channel = (tex_channel > -1) ? tex_channel : LLSelectMgr::getInstance()->getTextureChannel();
+ switch (tex_channel)
{
case 0:
@@ -1303,10 +1363,12 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
LLMessageSystem* msg = gMessageSystem;
if (mSource == SOURCE_NOTECARD)
{
+ LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard");
msg->newMessageFast(_PREHASH_RezObjectFromNotecard);
}
else
{
+ LLUIUsage::instance().logCommand("Object.RezObject");
msg->newMessageFast(_PREHASH_RezObject);
}
msg->nextBlockFast(_PREHASH_AgentData);
@@ -1628,6 +1690,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
case DAD_MESH:
case DAD_CATEGORY:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data;
if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID())
@@ -1982,6 +2045,17 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
dropTextureOneFace(obj, face, item, mSource, mSourceID);
}
}
+ else if (cargo_type == DAD_MATERIAL)
+ {
+ if ((mask & MASK_SHIFT))
+ {
+ dropMaterialAllFaces(obj, item, mSource, mSourceID);
+ }
+ else
+ {
+ dropMaterialOneFace(obj, face, item, mSource, mSourceID);
+ }
+ }
else if (cargo_type == DAD_MESH)
{
dropMesh(obj, item, mSource, mSourceID);
@@ -2010,6 +2084,12 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject(
return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE);
}
+EAcceptance LLToolDragAndDrop::dad3dMaterialObject(
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ return dad3dApplyToObject(obj, face, mask, drop, DAD_MATERIAL);
+}
+
EAcceptance LLToolDragAndDrop::dad3dMeshObject(
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 24a712029c..bf35840964 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -94,7 +94,7 @@ public:
// deal with permissions of object, etc. returns TRUE if drop can
// proceed, otherwise FALSE.
- static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
+ static BOOL handleDropMaterialProtections(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id);
@@ -168,6 +168,8 @@ protected:
MASK mask, BOOL drop);
EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
+ EAcceptance dad3dMaterialObject(LLViewerObject* obj, S32 face,
+ MASK mask, BOOL drop);
EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
// EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face,
@@ -244,11 +246,20 @@ public:
static void dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face,
LLInventoryItem* item,
ESource source,
- const LLUUID& src_id);
+ const LLUUID& src_id,
+ S32 tex_channel = -1);
static void dropTextureAllFaces(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,
const LLUUID& src_id);
+ static void dropMaterialOneFace(LLViewerObject* hit_obj, S32 hit_face,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id);
+ static void dropMaterialAllFaces(LLViewerObject* hit_obj,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id);
static void dropMesh(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 43deac60d9..5fb83bf08e 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -71,6 +71,7 @@
#include "llui.h"
#include "llweb.h"
#include "pipeline.h" // setHighlightObject
+#include "lluiusage.h"
extern BOOL gDebugClicks;
@@ -568,6 +569,8 @@ bool LLToolPie::walkToClickedLocation()
return false;
}
+ LLUIUsage::instance().logCommand("Agent.WalkToClickedLocation");
+
LLPickInfo saved_pick = mPick;
if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
{
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 814bade56a..7cdd7cc5c8 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -62,6 +62,7 @@
#include "llprimitive.h"
#include "llwindow.h" // incBusyCount()
#include "material_codes.h"
+#include "lluiusage.h"
const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f);
@@ -227,6 +228,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
}
+ LLUIUsage::instance().logCommand("Build.ObjectAdd");
gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index e52bc0b015..c6f3905ddc 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -65,7 +65,8 @@ BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
// do immediate pick query
BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
- mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
+ BOOL pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects");
+ mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged);
// Pass mousedown to agent
LLTool::handleMouseDown(x, y, mask);
@@ -84,13 +85,13 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
}
BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly");
BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly");
-
- // *NOTE: These settings must be cleaned up at bottom of function.
+
+ // *NOTE: These settings must be cleaned up at bottom of function.
if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar)
{
gSavedSettings.setBOOL("SelectOwnedOnly", FALSE);
gSavedSettings.setBOOL("SelectMovableOnly", FALSE);
- LLSelectMgr::getInstance()->setForceSelection(TRUE);
+ LLSelectMgr::getInstance()->setForceSelection(TRUE);
}
BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL);
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index 4804ef6ddc..481086f760 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -88,6 +88,7 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE));
addEntry(LLViewerAssetType::AT_SETTINGS, new ViewerAssetEntry(DAD_SETTINGS));
+ addEntry(LLViewerAssetType::AT_MATERIAL, new ViewerAssetEntry(DAD_MATERIAL));
};
EDragAndDropType LLViewerAssetType::lookupDragAndDropType(EType asset_type)
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 3f7e8531fb..3eb9f9eda2 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -50,6 +50,10 @@
#include "llpreviewnotecard.h"
#include "llpreviewgesture.h"
#include "llcoproceduremanager.h"
+#include "llthread.h"
+#include "llkeyframemotion.h"
+#include "lldatapacker.h"
+#include "llvoavatarself.h"
void dialog_refresh_all();
@@ -450,9 +454,62 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
errorLabel = "DoNotSupportBulkAnimationUpload";
error = true;
}
- else if (assetType == LLAssetType::AT_ANIMATION)
+ else if (exten == "anim")
+ {
+ // Default unless everything succeeds
+ errorLabel = "ProblemWithFile";
+ error = true;
+
+ // read from getFileName()
+ LLAPRFile infile;
+ infile.open(getFileName(),LL_APR_RB);
+ if (!infile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL;
+ errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str());
+ }
+ else
+ {
+ S32 size = LLAPRFile::size(getFileName());
+ U8* buffer = new U8[size];
+ S32 size_read = infile.read(buffer,size);
+ if (size_read != size)
+ {
+ errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read);
+ }
+ else
+ {
+ LLDataPackerBinaryBuffer dp(buffer, size);
+ LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId());
+ motionp->setCharacter(gAgentAvatarp);
+ if (motionp->deserialize(dp, getAssetId(), false))
+ {
+ // write to temp file
+ bool succ = motionp->dumpToFile(filename);
+ if (succ)
+ {
+ assetType = LLAssetType::AT_ANIMATION;
+ errorLabel = "";
+ error = false;
+ }
+ else
+ {
+ errorMessage = "Failed saving temporary animation file";
+ }
+ }
+ else
+ {
+ errorMessage = "Failed reading animation file";
+ }
+ }
+ }
+ }
+ else
{
- filename = getFileName();
+ // Unknown extension
+ errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
+ errorLabel = "ErrorMessage";
+ error = TRUE;;
}
if (error)
@@ -497,6 +554,67 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
}
//=========================================================================
+LLNewBufferedResourceUploadInfo::LLNewBufferedResourceUploadInfo(
+ const std::string& buffer,
+ const LLAssetID& asset_id,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ LLAssetType::EType assetType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost,
+ bool show_inventory,
+ uploadFinish_f finish)
+ : LLResourceUploadInfo(name, description, compressionInfo,
+ destinationType, inventoryType,
+ nextOWnerPerms, groupPerms, everyonePerms, expectedCost, show_inventory)
+ , mBuffer(buffer)
+ , mFinishFn(finish)
+{
+ setAssetType(assetType);
+ setAssetId(asset_id);
+}
+
+LLSD LLNewBufferedResourceUploadInfo::prepareUpload()
+{
+ if (getAssetId().isNull())
+ generateNewAssetId();
+
+ LLSD result = exportTempFile();
+ if (result.has("error"))
+ return result;
+
+ return LLResourceUploadInfo::prepareUpload();
+}
+
+LLSD LLNewBufferedResourceUploadInfo::exportTempFile()
+{
+ std::string filename = gDirUtilp->getTempFilename();
+
+ // copy buffer to the cache for upload
+ LLFileSystem file(getAssetId(), getAssetType(), LLFileSystem::APPEND);
+ file.write((U8*) mBuffer.c_str(), mBuffer.size());
+
+ return LLSD();
+}
+
+LLUUID LLNewBufferedResourceUploadInfo::finishUpload(LLSD &result)
+{
+ LLUUID newItemId = LLResourceUploadInfo::finishUpload(result);
+
+ if (mFinishFn)
+ {
+ mFinishFn(result["new_asset"].asUUID(), result);
+ }
+
+ return newItemId;
+}
+
+//=========================================================================
LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish) :
LLResourceUploadInfo(std::string(), std::string(), 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
0, 0, 0, 0),
@@ -863,6 +981,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
{
args["FILE"] = uploadInfo->getDisplayName();
args["REASON"] = reason;
+ args["ERROR"] = reason;
}
LLNotificationsUtil::add(label, args);
diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h
index e56ba7d8f7..9eddcfbd0e 100644
--- a/indra/newview/llviewerassetupload.h
+++ b/indra/newview/llviewerassetupload.h
@@ -168,6 +168,41 @@ private:
};
//-------------------------------------------------------------------------
+// use when you have a resource in memory and you want to make a new inventory item
+class LLNewBufferedResourceUploadInfo : public LLResourceUploadInfo
+{
+public:
+ typedef std::function<void(LLUUID newAssetId, LLSD response)> uploadFinish_f;
+
+ LLNewBufferedResourceUploadInfo(
+ const std::string& buffer,
+ const LLAssetID& asset_id,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ LLAssetType::EType assetType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost,
+ bool show_inventory,
+ uploadFinish_f finish);
+
+ virtual LLSD prepareUpload();
+
+protected:
+
+ virtual LLSD exportTempFile();
+ virtual LLUUID finishUpload(LLSD &result);
+
+private:
+ uploadFinish_f mFinishFn;
+ std::string mBuffer;
+};
+
+//-------------------------------------------------------------------------
class LLBufferedAssetUploadInfo : public LLResourceUploadInfo
{
public:
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index 782285ce36..febae36ae8 100644
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -33,8 +33,6 @@
// comment out to turn off wind
#define kAUDIO_ENABLE_WIND
//#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water
-#define kAUDIO_NUM_BUFFERS 30
-#define kAUDIO_NUM_SOURCES 30
void init_audio();
void audio_update_volume(bool force_update = true);
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index 549778a841..b5841772ed 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -47,15 +47,14 @@ public:
typedef enum
{
CAMERA_WORLD = 0,
- CAMERA_SHADOW0,
- CAMERA_SHADOW1,
- CAMERA_SHADOW2,
- CAMERA_SHADOW3,
- CAMERA_SHADOW4,
- CAMERA_SHADOW5,
+ CAMERA_SUN_SHADOW0,
+ CAMERA_SUN_SHADOW1,
+ CAMERA_SUN_SHADOW2,
+ CAMERA_SUN_SHADOW3,
+ CAMERA_SPOT_SHADOW0,
+ CAMERA_SPOT_SHADOW1,
CAMERA_WATER0,
CAMERA_WATER1,
- CAMERA_GI_SOURCE,
NUM_CAMERAS
} eCameraID;
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 602597a86b..98627f8313 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -381,7 +381,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)
static bool handleUseOcclusionChanged(const LLSD& newvalue)
{
- LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery
+ LLPipeline::sUseOcclusion = (newvalue.asBoolean()
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
return true;
}
@@ -434,9 +434,25 @@ static bool handleRenderLocalLightsChanged(const LLSD& newvalue)
return true;
}
+static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)
+{
+ if (gPipeline.isInit())
+ {
+ LLPipeline::refreshCachedSettings();
+ gPipeline.updateRenderDeferred();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ gPipeline.resetVertexBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ }
+ return true;
+}
+
+#if 0 // DEPRECATED
+// NOTE: may be triggered by RenderDeferred OR RenderPBR changing, don't trust "newvalue"
static bool handleRenderDeferredChanged(const LLSD& newvalue)
{
- LLRenderTarget::sUseFBO = newvalue.asBoolean();
+ LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
if (gPipeline.isInit())
{
LLPipeline::refreshCachedSettings();
@@ -470,13 +486,7 @@ static bool handleRenderBumpChanged(const LLSD& newval)
}
return true;
}
-
-static bool handleRenderDebugGLChanged(const LLSD& newvalue)
-{
- gDebugGL = newvalue.asBoolean() || gDebugSession;
- gGL.clearErrors();
- return true;
-}
+#endif
static bool handleRenderDebugPipelineChanged(const LLSD& newvalue)
{
@@ -640,157 +650,185 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
////////////////////////////////////////////////////////////////////////////
+LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const std::string& setting)
+{
+ LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting);
+ if (cntrl_ptr.isNull())
+ {
+ LL_ERRS() << "Unable to set up setting listener for " << setting
+ << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
+ return cntrl_ptr;
+}
+
+void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void(const LLSD& newvalue)> callback)
+{
+ setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ callback(new_val);
+ });
+}
+
+void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void()> callback)
+{
+ setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ callback();
+ });
+}
+
void settings_setup_listeners()
{
- gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2));
- gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2));
- gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2));
- gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleWindowResized, _2));
- gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2));
- gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleShadowsResized, _2));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
- gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
- gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
- gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));
- gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2));
- gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2));
- gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2));
- gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2));
- gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2));
- gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2));
- gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _2));
- gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));
- gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderVSyncEnable")->getSignal()->connect(boost::bind(&handleVSyncChanged, _2));
- gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2));
- gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
- gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));
- gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2));
- gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
- gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
- gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
- gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _2));
- gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _2));
- gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUseVAO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
- gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2));
- gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2));
- gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2));
- gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2));
- gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2));
- gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus));
- gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus));
- gSavedSettings.getControl("AgentPause")->getSignal()->connect(boost::bind(&toggle_agent_pause, _2));
- gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2));
- gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2));
- gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2));
- gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
- gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
- gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
- gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
- gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged));
- gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2));
- gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2));
- gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2));
+ setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
+ setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
+ // DEPRECATED -- setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
+ // DEPRECATED - setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
+ // DEPRECATED - setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderReflectionProbeDetail", handleReflectionProbeDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
+ setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged);
+ setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
+ setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
+ setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged);
+ setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged);
+ setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged);
+ setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged);
+ setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate);
+ setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus);
+ setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus);
+ setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause);
+ setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel);
+ setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel);
+ setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost);
+ setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid);
+ setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged);
+ setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged);
+ setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged);
+ setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged);
+ setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged);
+
+ setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 4fc1bdbec3..ed3631be99 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -31,6 +31,7 @@
#include "llgl.h"
#include "llrender.h"
#include "llglheaders.h"
+#include "llgltfmateriallist.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewercontrol.h"
@@ -97,6 +98,7 @@ BOOL gResizeScreenTexture = FALSE;
BOOL gResizeShadowTexture = FALSE;
BOOL gWindowResized = FALSE;
BOOL gSnapshot = FALSE;
+BOOL gCubeSnapshot = FALSE;
BOOL gShaderProfileFrame = FALSE;
// This is how long the sim will try to teleport you before giving up.
@@ -160,7 +162,7 @@ void display_startup()
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
LLGLSUIDefault gls_ui;
gPipeline.disableLights();
@@ -193,15 +195,23 @@ void display_update_camera()
// Cut draw distance in half when customizing avatar,
// but on the viewer only.
F32 final_far = gAgentCamera.mDrawDistance;
- if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
+ if (gCubeSnapshot)
+ {
+ final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance");
+ }
+ else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
+
{
final_far *= 0.5f;
}
LLViewerCamera::getInstance()->setFar(final_far);
gViewerWindow->setup3DRender();
- // Update land visibility too
- LLWorld::getInstance()->setLandFarClip(final_far);
+ if (!gCubeSnapshot)
+ {
+ // Update land visibility too
+ LLWorld::getInstance()->setLandFarClip(final_far);
+ }
}
// Write some stats to LL_INFOS()
@@ -245,7 +255,7 @@ static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_CLASS("Class");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_BUMP("Image Update Bump");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_LIST("List");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_DELETE("Delete");
+static LLTrace::BlockTimerStatHandle FTM_MATERIALS_FLUSH("GLTF Materials Cleanup");
static LLTrace::BlockTimerStatHandle FTM_RESIZE_WINDOW("Resize Window");
static LLTrace::BlockTimerStatHandle FTM_HUD_UPDATE("HUD Update");
static LLTrace::BlockTimerStatHandle FTM_DISPLAY_UPDATE_GEOM("Update Geom");
@@ -739,7 +749,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
glh::matrix4f proj = get_current_projection();
glh::matrix4f mod = get_current_modelview();
glViewport(0,0,512,512);
- LLVOAvatar::updateFreezeCounter() ;
LLVOAvatar::updateImpostors();
@@ -755,7 +764,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkTextureChannels();
}
- glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
}
LLGLState::checkStates();
@@ -764,7 +773,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 3")
LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
- gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
gPipeline.generateHighlight(*LLViewerCamera::getInstance());
gPipeline.renderPhysicsDisplay();
}
@@ -800,12 +808,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gTextureList.updateImages(max_image_decode_time);
}
- /*{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_DELETE);
- //remove dead textures from GL
- LLImageGL::deleteDeadTextures();
- stop_glerror();
- }*/
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MATERIALS_FLUSH);
+ //remove dead gltf materials
+ gGLTFMaterialList.flushMaterials();
+ }
}
LLGLState::checkStates();
@@ -853,7 +860,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
glClearColor(0.5f, 0.5f, 0.5f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
@@ -905,19 +911,27 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (LLPipeline::sRenderDeferred)
{
- gPipeline.mDeferredScreen.bindTarget();
- glClearColor(1, 0, 1, 1);
- gPipeline.mDeferredScreen.clear();
+ gPipeline.mRT->deferredScreen.bindTarget();
+ if (gUseWireframe)
+ {
+ F32 g = 0.5f;
+ glClearColor(g, g, g, 1.f);
+ }
+ else
+ {
+ glClearColor(1, 0, 1, 1);
+ }
+ gPipeline.mRT->deferredScreen.clear();
}
else
{
- gPipeline.mScreen.bindTarget();
+ gPipeline.mRT->screen.bindTarget();
if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
{
const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
}
- gPipeline.mScreen.clear();
+ gPipeline.mRT->screen.clear();
}
gGL.setColorMask(true, false);
@@ -954,7 +968,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gGL.setColorMask(true, false);
if (LLPipeline::sRenderDeferred)
{
- gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
+ gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true);
}
else
{
@@ -987,19 +1001,19 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
- LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen);
+ LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen);
rt.flush();
- if (rt.sUseFBO)
+ /*if (rt.sUseFBO)
{
LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(),
rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
GL_NEAREST);
- }
+ }*/
if (LLPipeline::sRenderDeferred)
{
- gPipeline.renderDeferredLighting(&gPipeline.mScreen);
+ gPipeline.renderDeferredLighting();
}
LLPipeline::sUnderWaterRender = FALSE;
@@ -1046,6 +1060,119 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
+// WIP simplified copy of display() that does minimal work
+void display_cube_face()
+{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER);
+ LL_PROFILE_GPU_ZONE("display cube face");
+
+ llassert(!gSnapshot);
+ llassert(!gTeleportDisplay);
+ llassert(LLStartUp::getStartupState() >= STATE_PRECACHE);
+ llassert(!LLAppViewer::instance()->logoutRequestSent());
+ llassert(!gRestoreGL);
+
+ bool rebuild = false;
+
+ LLGLSDefault gls_default;
+ LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
+
+ LLVertexBuffer::unbind();
+
+ gPipeline.disableLights();
+
+ gPipeline.mBackfaceCull = TRUE;
+
+ gViewerWindow->setup3DViewport();
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ { //don't draw hud objects in this frame
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES))
+ { //don't draw hud particles in this frame
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
+ }
+
+ display_update_camera();
+
+ LLSpatialGroup::sNoDelete = TRUE;
+
+ S32 occlusion = LLPipeline::sUseOcclusion;
+ LLPipeline::sUseOcclusion = 0; // occlusion data is from main camera point of view, don't read or write it during cube snapshots
+ //gDepthDirty = TRUE; //let "real" render pipe know it can't trust the depth buffer for occlusion data
+
+ static LLCullResult result;
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
+ gPipeline.updateCull(*LLViewerCamera::getInstance(), result);
+
+ gGL.setColorMask(true, true);
+
+ glClearColor(0, 0, 0, 0);
+ gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
+
+ glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
+
+ {
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
+
+ if (rebuild)
+ {
+ //////////////////////////////////////
+ //
+ // rebuildPools
+ //
+ //
+ gPipeline.rebuildPools();
+ stop_glerror();
+ }
+ }
+
+ LLPipeline::sUseOcclusion = occlusion;
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
+
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
+
+ gGL.setColorMask(true, true);
+
+ gPipeline.mRT->deferredScreen.bindTarget();
+ if (gUseWireframe)
+ {
+ glClearColor(0.5f, 0.5f, 0.5f, 1.f);
+ }
+ else
+ {
+ glClearColor(1, 0, 1, 1);
+ }
+ gPipeline.mRT->deferredScreen.clear();
+
+ gGL.setColorMask(true, false);
+
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+
+ gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
+
+ gGL.setColorMask(true, true);
+
+ gPipeline.mRT->deferredScreen.flush();
+
+ gPipeline.renderDeferredLighting();
+
+ LLPipeline::sUnderWaterRender = FALSE;
+
+ // Finalize scene
+ //gPipeline.renderFinalize();
+
+ LLSpatialGroup::sNoDelete = FALSE;
+ gPipeline.clearReferences();
+
+ gPipeline.rebuildGroups();
+}
+
void render_hud_attachments()
{
gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -1108,6 +1235,8 @@ void render_hud_attachments()
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_POST_WATER);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
@@ -1124,7 +1253,7 @@ void render_hud_attachments()
gPipeline.stateSort(hud_cam, result);
- gPipeline.renderGeom(hud_cam);
+ gPipeline.renderGeomPostDeferred(hud_cam);
LLSpatialGroup::sNoDelete = FALSE;
//gPipeline.clearReferences();
@@ -1240,7 +1369,7 @@ bool setup_hud_matrices(const LLRect& screen_region)
void render_ui(F32 zoom_factor, int subfield)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
-
+ LL_PROFILE_GPU_ZONE("ui");
LLGLState::checkStates();
glh::matrix4f saved_view = get_current_modelview();
@@ -1261,10 +1390,10 @@ void render_ui(F32 zoom_factor, int subfield)
gGL.popMatrix();
}
- // Finalize scene
- gPipeline.renderFinalize();
-
{
+ // draw hud and 3D ui elements into screen render target so they'll be able to use
+ // the depth buffer (avoids extra copy of depth buffer per frame)
+ gPipeline.mRT->screen.bindTarget();
// SL-15709
// NOTE: Tracy only allows one ZoneScoped per function.
// Solutions are:
@@ -1281,41 +1410,45 @@ void render_ui(F32 zoom_factor, int subfield)
gPipeline.disableLights();
}
- {
- gGL.color4f(1,1,1,1);
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- if (!gDisconnected)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
- render_ui_3d();
- LLGLState::checkStates();
- }
- else
- {
- render_disconnected_background();
- }
+ gGL.color4f(1,1,1,1);
- LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
- render_ui_2d();
- LLGLState::checkStates();
- }
- gGL.flush();
+ bool render_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ if (render_ui)
+ {
+ if (!gDisconnected)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
+ render_ui_3d();
+ LLGLState::checkStates();
+ }
+ else
+ {
+ render_disconnected_background();
+ }
+ }
- gViewerWindow->setup2DRender();
- gViewerWindow->updateDebugText();
- gViewerWindow->drawDebugText();
+ gPipeline.mRT->screen.flush();
- LLVertexBuffer::unbind();
- }
+ // apply gamma correction and post effects before rendering 2D UI
+ gPipeline.renderFinalize();
- if (!gSnapshot)
- {
- set_current_modelview(saved_view);
- gGL.popMatrix();
- }
+ if (render_ui)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
+ LLHUDObject::renderAll();
+ render_ui_2d();
+ }
+
+ gViewerWindow->setup2DRender();
+ gViewerWindow->updateDebugText();
+ gViewerWindow->drawDebugText();
+ }
- } // Tracy integration
+ if (!gSnapshot)
+ {
+ set_current_modelview(saved_view);
+ gGL.popMatrix();
+ }
}
static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
@@ -1323,7 +1456,7 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
void swap()
{
LL_RECORD_BLOCK_TIME(FTM_SWAP);
-
+ LL_PROFILE_GPU_ZONE("swap");
if (gDisplaySwapBuffers)
{
gViewerWindow->getWindow()->swapBuffers();
@@ -1485,7 +1618,7 @@ void render_ui_2d()
LLView::sIsRectDirty = false;
LLRect t_rect;
- gPipeline.mUIScreen.bindTarget();
+ gPipeline.mRT->uiScreen.bindTarget();
gGL.setColorMask(true, true);
{
static const S32 pad = 8;
@@ -1517,7 +1650,7 @@ void render_ui_2d()
gViewerWindow->draw();
}
- gPipeline.mUIScreen.flush();
+ gPipeline.mRT->uiScreen.flush();
gGL.setColorMask(true, false);
LLView::sDirtyRect = t_rect;
@@ -1527,7 +1660,7 @@ void render_ui_2d()
LLGLDisable blend(GL_BLEND);
S32 width = gViewerWindow->getWindowWidthScaled();
S32 height = gViewerWindow->getWindowHeightScaled();
- gGL.getTexUnit(0)->bind(&gPipeline.mUIScreen);
+ gGL.getTexUnit(0)->bind(&gPipeline.mRT->uiScreen);
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.color4f(1,1,1,1);
gGL.texCoord2f(0, 0); gGL.vertex2i(0, 0);
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
new file mode 100644
index 0000000000..cec08c4f15
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -0,0 +1,226 @@
+/**
+ * @file llviewerdisplayname.cpp
+ * @brief Wrapper for display name functionality
+ *
+ * $LicenseInfo:firstyear=2010&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerdisplayname.h"
+
+// viewer includes
+#include "llagent.h"
+#include "llfloaterprofile.h"
+#include "llfloaterreg.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h"
+
+// library includes
+#include "llavatarnamecache.h"
+#include "llhttpnode.h"
+#include "llnotificationsutil.h"
+#include "llui.h" // getLanguage()
+
+namespace LLViewerDisplayName
+{
+ // Fired when viewer receives server response to display name change
+ set_name_signal_t sSetDisplayNameSignal;
+
+ // Fired when there is a change in the agent's name
+ name_changed_signal_t sNameChangedSignal;
+
+ void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)
+ {
+ sNameChangedSignal.connect(cb);
+ }
+
+ void doNothing() { }
+}
+
+void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
+{
+ // TODO: simple validation here
+
+ LLViewerRegion* region = gAgent.getRegion();
+ llassert(region);
+ std::string cap_url = region->getCapability("SetDisplayName");
+ if (cap_url.empty())
+ {
+ // this server does not support display names, report error
+ slot(false, "unsupported", LLSD());
+ return;
+ }
+
+ // People API requires both the old and new value to change a variable.
+ // Our display name will be in cache before the viewer's UI is available
+ // to request a change, so we can use direct lookup without callback.
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
+ {
+ slot(false, "name unavailable", LLSD());
+ return;
+ }
+
+ // People API expects array of [ "old value", "new value" ]
+ LLSD change_array = LLSD::emptyArray();
+ change_array.append(av_name.getDisplayName());
+ change_array.append(display_name);
+
+ LL_INFOS() << "Set name POST to " << cap_url << LL_ENDL;
+
+ // Record our caller for when the server sends back a reply
+ sSetDisplayNameSignal.connect(slot);
+
+ // POST the requested change. The sim will not send a response back to
+ // this request directly, rather it will send a separate message after it
+ // communicates with the back-end.
+ LLSD body;
+ body["display_name"] = change_array;
+ LLCoros::instance().launch("LLViewerDisplayName::SetDisplayNameCoro",
+ boost::bind(&LLViewerDisplayName::setDisplayNameCoro, cap_url, body));
+}
+
+void LLViewerDisplayName::setDisplayNameCoro(const std::string& cap_url, const LLSD& body)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("SetDisplayNameCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+ // People API can return localized error messages. Indicate our
+ // language preference via header.
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT_LANGUAGE, LLUI::getLanguage());
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, body, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to set display name. Status: " << status.toString() << LL_ENDL;
+ LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
+ LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+ }
+}
+
+class LLSetDisplayNameReply : public LLHTTPNode
+{
+ LOG_CLASS(LLSetDisplayNameReply);
+public:
+ /*virtual*/ void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body = input["body"];
+
+ S32 status = body["status"].asInteger();
+ bool success = (status == HTTP_OK);
+ std::string reason = body["reason"].asString();
+ LLSD content = body["content"];
+
+ LL_INFOS() << "status " << status << " reason " << reason << LL_ENDL;
+
+ // If viewer's concept of display name is out-of-date, the set request
+ // will fail with 409 Conflict. If that happens, fetch up-to-date
+ // name information.
+ if (status == HTTP_CONFLICT)
+ {
+ LLUUID agent_id = gAgent.getID();
+ // Flush stale data
+ LLAvatarNameCache::getInstance()->erase( agent_id );
+ // Queue request for new data: nothing to do on callback though...
+ // Note: no need to disconnect the callback as it never gets out of scope
+ LLAvatarNameCache::getInstance()->get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
+ // Kill name tag, as it is wrong
+ LLVOAvatar::invalidateNameTag( agent_id );
+ }
+
+ // inform caller of result
+ LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
+ LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+ }
+};
+
+
+class LLDisplayNameUpdate : public LLHTTPNode
+{
+ /*virtual*/ void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body = input["body"];
+ LLUUID agent_id = body["agent_id"];
+ std::string old_display_name = body["old_display_name"];
+ // By convention this record is called "agent" in the People API
+ LLSD name_data = body["agent"];
+
+ // Inject the new name data into cache
+ LLAvatarName av_name;
+ av_name.fromLLSD( name_data );
+
+ LL_INFOS() << "name-update now " << LLDate::now()
+ << " next_update " << LLDate(av_name.mNextUpdate)
+ << LL_ENDL;
+
+ // Name expiration time may be provided in headers, or we may use a
+ // default value
+ // *TODO: get actual headers out of ResponsePtr
+ //LLSD headers = response->mHeaders;
+ LLSD headers;
+ av_name.mExpires =
+ LLAvatarNameCache::getInstance()->nameExpirationFromHeaders(headers);
+
+ LLAvatarNameCache::getInstance()->insert(agent_id, av_name);
+
+ // force name tag to update
+ LLVOAvatar::invalidateNameTag(agent_id);
+
+ LLSD args;
+ args["OLD_NAME"] = old_display_name;
+ args["SLID"] = av_name.getUserName();
+ args["NEW_NAME"] = av_name.getDisplayName();
+ LLNotificationsUtil::add("DisplayNameUpdate", args);
+ if (agent_id == gAgent.getID())
+ {
+ LLViewerDisplayName::sNameChangedSignal();
+ }
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)));
+ if (profile_floater)
+ {
+ profile_floater->refreshName();
+ }
+ }
+};
+
+LLHTTPRegistration<LLSetDisplayNameReply>
+ gHTTPRegistrationMessageSetDisplayNameReply(
+ "/message/SetDisplayNameReply");
+
+LLHTTPRegistration<LLDisplayNameUpdate>
+ gHTTPRegistrationMessageDisplayNameUpdate(
+ "/message/DisplayNameUpdate");
diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h
new file mode 100644
index 0000000000..337aaa68b6
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.h
@@ -0,0 +1,55 @@
+/**
+ * @file llviewerdisplayname.h
+ * @brief Wrapper for display name functionality
+ *
+ * $LicenseInfo:firstyear=2010&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$
+ */
+
+#ifndef LLVIEWERDISPLAYNAME_H
+#define LLVIEWERDISPLAYNAME_H
+
+#include <boost/signals2.hpp>
+
+class LLSD;
+class LLUUID;
+
+namespace LLViewerDisplayName
+{
+ typedef boost::signals2::signal<
+ void (bool success, const std::string& reason, const LLSD& content)>
+ set_name_signal_t;
+ typedef set_name_signal_t::slot_type set_name_slot_t;
+
+ typedef boost::signals2::signal<void (void)> name_changed_signal_t;
+ typedef name_changed_signal_t::slot_type name_changed_slot_t;
+
+ // Sends an update to the server to change a display name
+ // and call back when done. May not succeed due to service
+ // unavailable or name not available.
+ void set(const std::string& display_name, const set_name_slot_t& slot);
+
+ void setDisplayNameCoro(const std::string& cap_url, const LLSD& body);
+
+ void addNameChangedCallback(const name_changed_signal_t::slot_type& cb);
+}
+
+#endif // LLVIEWERDISPLAYNAME_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 5a3a358173..f5ccc238c0 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -57,11 +57,13 @@
#include "llfloatercamera.h"
#include "llfloatercamerapresets.h"
#include "llfloaterchatvoicevolume.h"
+#include "llfloaterclassified.h"
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
#include "llfloatercreatelandmark.h"
#include "llfloaterdeleteprefpreset.h"
#include "llfloaterdestinations.h"
+#include "llfloaterdisplayname.h"
#include "llfloatereditextdaycycle.h"
#include "llfloaterenvironmentadjust.h"
#include "llfloaterexperienceprofile.h"
@@ -111,6 +113,7 @@
#include "llfloaterpreference.h"
#include "llfloaterpreferenceviewadvanced.h"
#include "llfloaterpreviewtrash.h"
+#include "llfloaterprofile.h"
#include "llfloaterproperties.h"
#include "llfloaterregiondebugconsole.h"
#include "llfloaterregioninfo.h"
@@ -140,7 +143,6 @@
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
#include "llfloaterwebcontent.h"
-#include "llfloaterwebprofile.h"
#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindowsize.h"
@@ -151,10 +153,11 @@
#include "llinspectobject.h"
#include "llinspectremoteobject.h"
#include "llinspecttoast.h"
+#include "llmaterialeditor.h"
#include "llmoveview.h"
#include "llfloaterimnearbychat.h"
#include "llpanelblockedlist.h"
-#include "llpanelclassified.h"
+#include "llpanelprofileclassifieds.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@@ -227,6 +230,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
+ LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
@@ -274,6 +278,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectRemoteObjectUtil::registerFloater();
LLFloaterVoiceVolumeUtil::registerFloater();
LLNotificationsUI::registerFloater();
+ LLFloaterDisplayNameUtil::registerFloater();
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
@@ -315,7 +320,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
- LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>);
@@ -332,6 +336,8 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>);
LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
+ LLFloaterReg::add("material_editor", "floater_material_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLMaterialEditor>);
+
LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml", &LLFloaterReg::build<LLFloaterTestInspectors>);
//LLFloaterReg::add("test_list_view", "floater_test_list_view.xml",&LLFloaterReg::build<LLFloaterTestListView>);
@@ -362,8 +368,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
- LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
- LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
+ LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index f770db31dd..c8d4aae8fd 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -134,6 +134,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_SETTINGS, new ViewerFolderEntry("Settings", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
+ addEntry(LLFolderType::FT_MATERIAL, new ViewerFolderEntry("Materials", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible");
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Received Items", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 55ac817479..b4feafb7ff 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -147,6 +147,7 @@ LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary()
mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
+ mInventoryItemsDict["New Material"] = LLTrans::getString("New Material");
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
@@ -998,6 +999,21 @@ void create_notecard_cb(const LLUUID& inv_item)
}
}
+void create_gltf_material_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ set_default_permissions(item, "Materials");
+
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
LLInventoryCallbackManager gInventoryCallbacks;
void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
@@ -1622,6 +1638,13 @@ void create_new_item(const std::string& name,
next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Notecards");
break;
}
+
+ case LLInventoryType::IT_MATERIAL:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_gltf_material_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials");
+ break;
+ }
default:
break;
}
@@ -1672,6 +1695,7 @@ void remove_folder_contents(const LLUUID& category, bool keep_outfit_links,
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
+const std::string NEW_MATERIAL_NAME = "New Material"; // *TODO:Translate? (probably not)
// ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
@@ -1727,6 +1751,15 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
LLInventoryType::IT_GESTURE,
PERM_ALL); // overridden in create_new_item
}
+ else if ("material" == type_name)
+ {
+ const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ create_new_item(NEW_MATERIAL_NAME,
+ parent_id,
+ LLAssetType::AT_MATERIAL,
+ LLInventoryType::IT_MATERIAL,
+ PERM_ALL); // overridden in create_new_item
+ }
else if (("sky" == type_name) || ("water" == type_name) || ("daycycle" == type_name))
{
LLSettingsType::type_e stype(LLSettingsType::ST_NONE);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 812f804ea9..a1cb152e1e 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -48,7 +48,7 @@
#include "llmutelist.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
-#include "llpanelprofile.h"
+#include "llavataractions.h"
#include "llparcel.h"
#include "llpluginclassmedia.h"
#include "llurldispatcher.h"
@@ -3194,7 +3194,7 @@ bool LLViewerMediaImpl::isForcedUnloaded() const
}
// If this media's class is not supposed to be shown, unload
- if (!shouldShowBasedOnClass())
+ if (!shouldShowBasedOnClass() || isObscured())
{
return true;
}
@@ -3881,6 +3881,40 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
//////////////////////////////////////////////////////////////////////////////////////////
//
+bool LLViewerMediaImpl::isObscured() const
+{
+ if (getUsedInUI() || isParcelMedia() || isAttachedToHUD()) return false;
+
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!agent_parcel)
+ {
+ return false;
+ }
+
+ if (agent_parcel->getObscureMOAP() && !isInAgentParcel())
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLViewerMediaImpl::isAttachedToHUD() const
+{
+ std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
+ std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
+ for ( ; iter != end; iter++)
+ {
+ if ((*iter)->isHUDAttachment())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const
{
bool result = false;
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 806692929a..f1f42afd81 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -411,6 +411,8 @@ public:
void cancelMimeTypeProbe();
+ bool isAttachedToHUD() const;
+
// Is this media attached to an avatar *not* self
bool isAttachedToAnotherAvatar() const;
@@ -423,6 +425,7 @@ public:
private:
bool isAutoPlayable() const;
bool shouldShowBasedOnClass() const;
+ bool isObscured() const;
static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj);
static bool isObjectInAgentParcel(LLVOVolume *obj);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index d95948ac04..e1b92e5f2e 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -33,10 +33,11 @@
#include "llviewermenu.h"
// linden library includes
-#include "llavatarnamecache.h" // IDEVO
+#include "llavatarnamecache.h" // IDEVO (I Are Not Men!)
+#include "llcombobox.h"
+#include "llcoros.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
-#include "llcombobox.h"
#include "llinventorypanel.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
@@ -53,6 +54,7 @@
#include "llcompilequeue.h"
#include "llconsole.h"
#include "lldebugview.h"
+#include "lldiskcache.h"
#include "llenvironment.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
@@ -91,8 +93,10 @@
#include "llpanelblockedlist.h"
#include "llpanelmaininventory.h"
#include "llmarketplacefunctions.h"
+#include "llmaterialeditor.h"
#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmoveview.h"
+#include "llnavigationbar.h"
#include "llparcel.h"
#include "llrootview.h"
#include "llsceneview.h"
@@ -267,16 +271,11 @@ void handle_reset_view();
void handle_duplicate_in_place(void*);
-
void handle_object_owner_self(void*);
void handle_object_owner_permissive(void*);
void handle_object_lock(void*);
void handle_object_asset_ids(void*);
void force_take_copy(void*);
-#ifdef _CORY_TESTING
-void force_export_copy(void*);
-void force_import_geometry(void*);
-#endif
void handle_force_parcel_owner_to_me(void*);
void handle_force_parcel_to_content(void*);
@@ -398,7 +397,19 @@ void set_merchant_SLM_menu()
// All other cases (new merchant, not merchant, migrated merchant): show the new Marketplace Listings menu and enable the tool
gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(TRUE);
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
- gToolBarView->enableCommand(command->id(), true);
+ gToolBarView->enableCommand(command->id(), true);
+
+ const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ if (marketplacelistings_id.isNull())
+ {
+ U32 mkt_status = LLMarketplaceData::instance().getSLMStatus();
+ bool is_merchant = (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT) || (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MIGRATED_MERCHANT);
+ if (is_merchant)
+ {
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true);
+ LL_WARNS("SLM") << "Creating the marketplace listings folder for a merchant" << LL_ENDL;
+ }
+ }
}
void check_merchant_status(bool force)
@@ -1081,6 +1092,10 @@ U64 info_display_from_string(std::string info_display)
{
return LLPipeline::RENDER_DEBUG_IMPOSTORS;
}
+ else if ("reflection probes" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES;
+ }
else
{
LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL;
@@ -1197,6 +1212,7 @@ class LLAdvancedCheckFrameTest : public view_listener_t
///////////////////////////
// SELECTED TEXTURE INFO //
+//
///////////////////////////
@@ -1218,24 +1234,6 @@ class LLAdvancedToggleWireframe : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
gUseWireframe = !(gUseWireframe);
- gWindowResized = TRUE;
-
- LLPipeline::updateRenderDeferred();
-
- if (gUseWireframe)
- {
- gInitialDeferredModeForWireframe = LLPipeline::sRenderDeferred;
- }
-
- gPipeline.resetVertexBuffers();
-
- if (!gUseWireframe && !gInitialDeferredModeForWireframe && LLPipeline::sRenderDeferred != bool(gInitialDeferredModeForWireframe) && gPipeline.isInit())
- {
- LLPipeline::refreshCachedSettings();
- gPipeline.releaseGLBuffers();
- gPipeline.createGLBuffers();
- LLViewerShaderMgr::instance()->setShaders();
- }
return true;
}
@@ -1245,8 +1243,7 @@ class LLAdvancedCheckWireframe : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gUseWireframe;
- return new_value;
+ return gUseWireframe;
}
};
@@ -2088,6 +2085,32 @@ class LLAdvancedDropPacket : public view_listener_t
}
};
+//////////////////////
+// PURGE DISK CACHE //
+//////////////////////
+
+
+class LLAdvancedPurgeDiskCache : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ llassert_always(main_queue);
+ llassert_always(general_queue);
+ main_queue->postTo(
+ general_queue,
+ []() // Work done on general queue
+ {
+ LLDiskCache::getInstance()->purge();
+ // Nothing needed to return
+ },
+ [](){}); // Callback to main thread is empty as there is nothing left to do
+
+ return true;
+ }
+};
+
////////////////////
// EVENT Recorder //
@@ -2298,59 +2321,6 @@ class LLAdvancedCheckViewAdminOptions : public view_listener_t
}
};
-/////////////////////////////////////
-// Enable Object Object Occlusion ///
-/////////////////////////////////////
-class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
-
- bool new_value = gGLManager.mHasOcclusionQuery; // && LLFeatureManager::getInstance()->isFeatureAvailable(userdata.asString());
- return new_value;
-}
-};
-
-/////////////////////////////////////
-// Enable Framebuffer Objects ///
-/////////////////////////////////////
-class LLAdvancedEnableRenderFBO: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gGLManager.mHasFramebufferObject;
- return new_value;
- }
-};
-
-/////////////////////////////////////
-// Enable Deferred Rendering ///
-/////////////////////////////////////
-class LLAdvancedEnableRenderDeferred: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
- LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0;
- return new_value;
- }
-};
-
-/////////////////////////////////////
-// Enable Deferred Rendering sub-options
-/////////////////////////////////////
-class LLAdvancedEnableRenderDeferredOptions: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
- LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred");
- return new_value;
- }
-};
-
-
-
//////////////////
// ADMIN STATUS //
//////////////////
@@ -2395,6 +2365,7 @@ class LLAdvancedForceErrorLlerror : public view_listener_t
return true;
}
};
+
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2404,6 +2375,22 @@ class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
}
};
+class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLCoros::instance().launch(
+ "AdvancedForceErrorBadMemoryAccessCoro",
+ [](){
+ // Wait for one mainloop() iteration, letting the enclosing
+ // handleEvent() method return.
+ llcoro::suspend();
+ force_error_bad_memory_access(NULL);
+ });
+ return true;
+ }
+};
+
class LLAdvancedForceErrorInfiniteLoop : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2422,6 +2409,22 @@ class LLAdvancedForceErrorSoftwareException : public view_listener_t
}
};
+class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLCoros::instance().launch(
+ "AdvancedForceErrorSoftwareExceptionCoro",
+ [](){
+ // Wait for one mainloop() iteration, letting the enclosing
+ // handleEvent() method return.
+ llcoro::suspend();
+ force_error_software_exception(NULL);
+ });
+ return true;
+ }
+};
+
class LLAdvancedForceErrorDriverCrash : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2705,6 +2708,32 @@ void handle_object_touch()
send_ObjectDeGrab_message(object, pick);
}
+void handle_object_show_original()
+{
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object)
+ {
+ return;
+ }
+
+ LLViewerObject *parent = (LLViewerObject*)object->getParent();
+ while (parent)
+ {
+ if(parent->isAvatar())
+ {
+ break;
+ }
+ object = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
+
+ if (!object || object->isAvatar())
+ {
+ return;
+ }
+
+ show_item_original(object->getAttachmentItemID());
+}
static void init_default_item_label(const std::string& item_name)
@@ -2780,6 +2809,39 @@ void handle_object_open()
LLFloaterReg::showInstance("openobject");
}
+struct LLSelectedTEGetmatIdAndPermissions : public LLSelectedTEGetFunctor<LLUUID>
+{
+ LLSelectedTEGetmatIdAndPermissions() : mCanCopy(true), mCanModify(true), mCanTransfer(true) {}
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ mCanCopy &= (bool)object->permCopy();
+ mCanTransfer &= (bool)object->permTransfer();
+ mCanModify &= (bool)object->permModify();
+ // return true if all ids are identical
+ return object->getRenderMaterialID(te_index);
+ }
+ bool mCanCopy;
+ bool mCanModify;
+ bool mCanTransfer;
+};
+
+bool enable_object_edit_gltf_material()
+{
+ LLSelectedTEGetmatIdAndPermissions func;
+ LLUUID mat_id;
+ LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat_id);
+
+ return func.mCanModify;
+}
+
+bool enable_object_save_gltf_material()
+{
+ LLSelectedTEGetmatIdAndPermissions func;
+ LLUUID mat_id;
+ LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat_id);
+ return func.mCanCopy && mat_id.notNull();
+}
+
bool enable_object_open()
{
// Look for contents in root object, which is all the LLFloaterOpenObject
@@ -2845,37 +2907,42 @@ class LLObjectBuild : public view_listener_t
}
};
-void handle_object_edit()
+void update_camera()
{
- LLViewerParcelMgr::getInstance()->deselectLand();
+ LLViewerParcelMgr::getInstance()->deselectLand();
- if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
- {
- LLFloaterTools::sPreviousFocusOnAvatar = true;
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
+ {
+ LLFloaterTools::sPreviousFocusOnAvatar = true;
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ // always freeze camera in space, even if camera doesn't move
+ // so, for example, follow cam scripts can't affect you when in build mode
+ gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ }
+ else
+ {
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ LLViewerObject* selected_objectp = selection->getFirstRootObject();
+ if (selected_objectp)
+ {
+ // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
+ gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
+ gAgentCamera.cameraZoomIn(0.666f);
+ gAgentCamera.cameraOrbitOver(30.f * DEG_TO_RAD);
+ gViewerWindow->moveCursorToCenter();
+ }
+ }
+ }
+}
+
+void handle_object_edit()
+{
+ update_camera();
- if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
- {
- // always freeze camera in space, even if camera doesn't move
- // so, for example, follow cam scripts can't affect you when in build mode
- gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- }
- else
- {
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- LLViewerObject* selected_objectp = selection->getFirstRootObject();
- if (selected_objectp)
- {
- // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
- gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
- gAgentCamera.cameraZoomIn(0.666f);
- gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
- gViewerWindow->moveCursorToCenter();
- }
- }
- }
-
LLFloaterReg::showInstance("build");
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
@@ -2889,6 +2956,28 @@ void handle_object_edit()
return;
}
+void handle_object_edit_gltf_material()
+{
+ if (!LLFloaterReg::instanceVisible("build"))
+ {
+ handle_object_edit(); // does update_camera();
+ }
+ else
+ {
+ update_camera();
+
+ LLViewerJoystick::getInstance()->moveObjects(true);
+ LLViewerJoystick::getInstance()->setNeedsReset(true);
+ }
+
+ LLMaterialEditor::loadLive();
+}
+
+void handle_object_save_gltf_material()
+{
+ LLMaterialEditor::loadObjectSave();
+}
+
void handle_attachment_edit(const LLUUID& inv_item_id)
{
if (isAgentAvatarValid())
@@ -3589,6 +3678,11 @@ bool my_profile_visible()
return floaterp && floaterp->isInVisibleChain();
}
+bool picks_tab_visible()
+{
+ return my_profile_visible() && LLAvatarActions::isPickTabSelected(gAgentID);
+}
+
bool enable_freeze_eject(const LLSD& avatar_id)
{
// Use avatar_id if available, otherwise default to right-click avatar
@@ -4169,23 +4263,9 @@ bool is_object_sittable()
}
}
-
// only works on pie menu
-void handle_object_sit_or_stand()
+void handle_object_sit(LLViewerObject *object, const LLVector3 &offset)
{
- LLPickInfo pick = LLToolPie::getInstance()->getPick();
- LLViewerObject *object = pick.getObject();;
- if (!object || pick.mPickType == LLPickInfo::PICK_FLORA)
- {
- return;
- }
-
- if (sitting_on_selection())
- {
- gAgent.standUp();
- return;
- }
-
// get object selection offset
if (object && object->getPCode() == LL_PCODE_VOLUME)
@@ -4197,12 +4277,42 @@ void handle_object_sit_or_stand()
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
- gMessageSystem->addVector3Fast(_PREHASH_Offset, pick.mObjectOffset);
+ gMessageSystem->addVector3Fast(_PREHASH_Offset, offset);
object->getRegion()->sendReliableMessage();
}
}
+void handle_object_sit_or_stand()
+{
+ LLPickInfo pick = LLToolPie::getInstance()->getPick();
+ LLViewerObject *object = pick.getObject();
+ if (!object || pick.mPickType == LLPickInfo::PICK_FLORA)
+ {
+ return;
+ }
+
+ if (sitting_on_selection())
+ {
+ gAgent.standUp();
+ return;
+ }
+
+ handle_object_sit(object, pick.mObjectOffset);
+}
+
+void handle_object_sit(const LLUUID& object_id)
+{
+ LLViewerObject* obj = gObjectList.findObject(object_id);
+ if (!obj)
+ {
+ return;
+ }
+
+ LLVector3 offset(0, 0, 0);
+ handle_object_sit(obj, offset);
+}
+
void near_sit_down_point(BOOL success, void *)
{
if (success)
@@ -5298,12 +5408,10 @@ class LLToolsEnablePathfindingRebakeRegion : public view_listener_t
{
bool returnValue = false;
- if (LLPathfindingManager::getInstance() != NULL)
- {
- LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance();
- returnValue = (rebakeInstance->canRebakeRegion() &&
- (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available));
- }
+ if (LLNavigationBar::instanceExists())
+ {
+ returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable();
+ }
return returnValue;
}
};
@@ -6266,6 +6374,29 @@ class LLAvatarToggleMyProfile : public view_listener_t
}
};
+class LLAvatarTogglePicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID());
+ if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome()))
+ {
+ instance->setMinimized(FALSE);
+ instance->setFocus(TRUE);
+ LLAvatarActions::showPicks(gAgent.getID());
+ }
+ else if (picks_tab_visible())
+ {
+ instance->closeFloater();
+ }
+ else
+ {
+ LLAvatarActions::showPicks(gAgent.getID());
+ }
+ return true;
+ }
+};
+
class LLAvatarToggleSearch : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6337,6 +6468,24 @@ class LLAvatarResetSkeletonAndAnimations : public view_listener_t
}
};
+class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ if (avatar)
+ {
+ avatar->resetSkeleton(true);
+ }
+ else
+ {
+ gAgentAvatarp->resetSkeleton(true);
+ }
+ return true;
+ }
+};
+
+
class LLAvatarAddContact : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6718,6 +6867,15 @@ class LLShowAgentProfile : public view_listener_t
}
};
+class LLShowAgentProfilePicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAvatarActions::showPicks(gAgent.getID());
+ return true;
+ }
+};
+
class LLToggleAgentProfile : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -7964,6 +8122,18 @@ class LLToolsSelectOnlyMovableObjects : public view_listener_t
}
};
+class LLToolsSelectInvisibleObjects : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ BOOL cur_val = gSavedSettings.getBOOL("SelectInvisibleObjects");
+
+ gSavedSettings.setBOOL("SelectInvisibleObjects", !cur_val);
+
+ return true;
+ }
+};
+
class LLToolsSelectBySurrounding : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -8296,6 +8466,12 @@ void handle_cache_clear_immediately()
LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);
}
+void handle_rebuild_reflection_probes()
+{
+ gPipeline.mReflectionMapManager.rebuild();
+}
+
+
void handle_web_content_test(const LLSD& param)
{
std::string url = param.asString();
@@ -9187,6 +9363,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
+ view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects");
view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
@@ -9255,10 +9432,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
// Develop > Render
- view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
- view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");
- view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
- view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions");
view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");
view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame");
@@ -9355,6 +9528,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket");
+ // Advanced > Cache
+ view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache");
+
// Advanced > Recorder
view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
@@ -9365,8 +9541,10 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
+ view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
+ view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
@@ -9392,6 +9570,8 @@ void initialize_menus()
//Develop (clear cache immediately)
commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
+ //Develop (override environment map)
+ commit.add("Develop.RebuildReflectionProbes", boost::bind(&handle_rebuild_reflection_probes));
// Admin >Object
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
@@ -9439,11 +9619,14 @@ void initialize_menus()
enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
+ view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");
view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");
view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
+ view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
+ enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible));
commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
@@ -9453,6 +9636,7 @@ void initialize_menus()
// Object pie menu
view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
commit.add("Object.Touch", boost::bind(&handle_object_touch));
+ commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original));
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
commit.add("Object.Delete", boost::bind(&handle_object_delete));
view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
@@ -9467,10 +9651,15 @@ void initialize_menus()
commit.add("Object.Buy", boost::bind(&handle_buy));
commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material));
+ commit.add("Object.SaveGLTFMaterial", boost::bind(&handle_object_save_gltf_material));
commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
commit.add("Object.Open", boost::bind(&handle_object_open));
commit.add("Object.Take", boost::bind(&handle_take));
commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
+ enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material));
+ enable.add("Object.EnableSaveGLTFMaterial", boost::bind(&enable_object_save_gltf_material));
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
@@ -9519,6 +9708,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");
view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
+ view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks");
view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 36b6971c81..0673652e61 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -90,6 +90,8 @@ void handle_gestures(void*);
void handle_sit_down(void*);
void handle_object_build(void*);
void handle_object_touch();
+bool enable_object_edit_gltf_material();
+bool enable_object_save_gltf_material();
bool enable_object_open();
void handle_object_open();
@@ -108,6 +110,8 @@ void handle_zoom_to_object(LLUUID object_id);
void handle_object_return();
void handle_object_delete();
void handle_object_edit();
+void handle_object_edit_gltf_material();
+void handle_object_save_gltf_material();
void handle_attachment_edit(const LLUUID& inv_item_id);
void handle_attachment_touch(const LLUUID& inv_item_id);
@@ -135,6 +139,7 @@ void handle_save_snapshot(void *);
void handle_toggle_flycam();
void handle_object_sit_or_stand();
+void handle_object_sit(const LLUUID& object_id);
void handle_give_money_dialog();
bool enable_pay_object();
bool enable_buy_object();
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 28ff69eaf5..ffa2ce865e 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -37,6 +37,7 @@
#include "llbuycurrencyhtml.h"
#include "llfloatermap.h"
#include "llfloatermodelpreview.h"
+#include "llmaterialeditor.h"
#include "llfloatersnapshot.h"
#include "llfloateroutfitsnapshot.h"
#include "llimage.h"
@@ -101,6 +102,20 @@ class LLFileEnableUploadModel : public view_listener_t
}
};
+class LLFileEnableUploadMaterial : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::findInstance("material_editor");
+ if (me && me->isShown())
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
class LLMeshEnabled : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -234,6 +249,16 @@ LLFilePickerReplyThread::~LLFilePickerReplyThread()
delete mFailureSignal;
}
+void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type & cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type & failure_cb)
+{
+ (new LLFilePickerReplyThread(cb, filter, get_multiple, failure_cb))->getFile();
+}
+
+void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type & cb, LLFilePicker::ESaveFilter filter, const std::string & proposed_name, const file_picked_signal_t::slot_type & failure_cb)
+{
+ (new LLFilePickerReplyThread(cb, filter, proposed_name, failure_cb))->getFile();
+}
+
void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
{
if (filenames.empty())
@@ -255,13 +280,13 @@ void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
LLMediaFilePicker::LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple)
: LLFilePickerThread(filter, get_multiple),
- mPlugin(plugin->getSharedPrt())
+ mPlugin(plugin->getSharedPtr())
{
}
LLMediaFilePicker::LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
: LLFilePickerThread(filter, proposed_name),
- mPlugin(plugin->getSharedPrt())
+ mPlugin(plugin->getSharedPtr())
{
}
@@ -277,14 +302,12 @@ void LLMediaFilePicker::notify(const std::vector<std::string>& filenames)
static std::string SOUND_EXTENSIONS = "wav";
static std::string IMAGE_EXTENSIONS = "tga bmp jpg jpeg png";
static std::string ANIM_EXTENSIONS = "bvh anim";
-#ifdef _CORY_TESTING
-static std::string GEOMETRY_EXTENSIONS = "slg";
-#endif
static std::string XML_EXTENSIONS = "xml";
static std::string SLOBJECT_EXTENSIONS = "slobject";
#endif
static std::string ALL_FILE_EXTENSIONS = "*.*";
static std::string MODEL_EXTENSIONS = "dae";
+static std::string MATERIAL_EXTENSIONS = "gltf glb";
std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
{
@@ -301,10 +324,8 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
return SLOBJECT_EXTENSIONS;
case LLFilePicker::FFLOAD_MODEL:
return MODEL_EXTENSIONS;
-#ifdef _CORY_TESTING
- case LLFilePicker::FFLOAD_GEOMETRY:
- return GEOMETRY_EXTENSIONS;
-#endif
+ case LLFilePicker::FFLOAD_MATERIAL:
+ return MATERIAL_EXTENSIONS;
case LLFilePicker::FFLOAD_XML:
return XML_EXTENSIONS;
case LLFilePicker::FFLOAD_ALL:
@@ -560,7 +581,7 @@ class LLFileUploadImage : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false);
return true;
}
};
@@ -573,7 +594,16 @@ class LLFileUploadModel : public view_listener_t
return TRUE;
}
};
-
+
+class LLFileUploadMaterial : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLMaterialEditor::importMaterial();
+ return TRUE;
+ }
+};
+
class LLFileUploadSound : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -582,7 +612,7 @@ class LLFileUploadSound : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false);
return true;
}
};
@@ -595,7 +625,7 @@ class LLFileUploadAnim : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false);
return true;
}
};
@@ -608,7 +638,7 @@ class LLFileUploadBulk : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true);
return true;
}
};
@@ -1104,6 +1134,7 @@ void init_menu_file()
view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound");
view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim");
view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel");
+ view_listener_t::addCommit(new LLFileUploadMaterial(), "File.UploadMaterial");
view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk");
view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow");
view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index beeac418d9..5c2caf9c51 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -115,14 +115,18 @@ class LLFilePickerReplyThread : public LLFilePickerThread
public:
typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)> file_picked_signal_t;
-
- LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
- LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
- ~LLFilePickerReplyThread();
+
+ static void startPicker(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ static void startPicker(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
virtual void notify(const std::vector<std::string>& filenames);
private:
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ ~LLFilePickerReplyThread();
+
+private:
LLFilePicker::ELoadFilter mLoadFilter;
LLFilePicker::ESaveFilter mSaveFilter;
file_picked_signal_t* mFilePickedSignal;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a886303563..e96047df14 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -33,6 +33,7 @@
#include "llavataractions.h"
#include "llavatarnamecache.h" // IDEVO HACK
#include "lleventtimer.h"
+#include "llfloatercreatelandmark.h"
#include "llfloaterreg.h"
#include "llfolderview.h"
#include "llfollowcamparams.h"
@@ -122,6 +123,7 @@
#include "llexperiencecache.h"
#include "llexperiencecache.h"
+#include "lluiusage.h"
extern void on_new_message(const LLSD& msg);
@@ -261,6 +263,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
{
case 0:
{
+ LLUIUsage::instance().logCommand("Agent.AcceptFriendship");
// accept
LLAvatarTracker::formFriendship(payload["from_id"]);
@@ -303,6 +306,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
// fall-through
case 2: // Send IM - decline and start IM session
{
+ LLUIUsage::instance().logCommand("Agent.DeclineFriendship");
// decline
// We no longer notify other viewers, but we DO still send
// the rejection to the simulator to delete the pending userop.
@@ -833,6 +837,11 @@ void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accep
EInstantMessage type = accept_invite ? IM_GROUP_INVITATION_ACCEPT : IM_GROUP_INVITATION_DECLINE;
+ if (accept_invite)
+ {
+ LLUIUsage::instance().logCommand("Group.Join");
+ }
+
send_improved_im(group_id,
std::string("name"),
std::string("message"),
@@ -1414,7 +1423,8 @@ bool check_asset_previewable(const LLAssetType::EType asset_type)
(asset_type == LLAssetType::AT_TEXTURE) ||
(asset_type == LLAssetType::AT_ANIMATION) ||
(asset_type == LLAssetType::AT_SCRIPT) ||
- (asset_type == LLAssetType::AT_SOUND);
+ (asset_type == LLAssetType::AT_SOUND) ||
+ (asset_type == LLAssetType::AT_MATERIAL);
}
void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_name)
@@ -1519,6 +1529,9 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
case LLAssetType::AT_SOUND:
LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus);
break;
+ case LLAssetType::AT_MATERIAL:
+ LLFloaterReg::showInstance("material editor", LLSD(obj_id), take_focus);
+ break;
default:
LL_DEBUGS("Messaging") << "No preview method for previewable asset type : " << LLAssetType::lookupHumanReadable(asset_type) << LL_ENDL;
break;
@@ -1560,6 +1573,17 @@ bool highlight_offered_object(const LLUUID& obj_id)
}
}
+ if (obj->getType() == LLAssetType::AT_LANDMARK)
+ {
+ LLFloaterCreateLandmark *floater = LLFloaterReg::findTypedInstance<LLFloaterCreateLandmark>("add_landmark");
+ if (floater && floater->getItem() && floater->getItem()->getUUID() == obj_id)
+ {
+ // LLFloaterCreateLandmark is supposed to handle this,
+ // keep landmark creation floater at the front
+ return false;
+ }
+ }
+
return true;
}
@@ -5805,15 +5829,15 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit)
continue;
- if (script_perm.question == "JoinAnExperience")
- { // Some experience only permissions do not have an explicit permission bit. Add them here.
- script_question += " " + LLTrans::getString("ForceSitAvatar") + "\n";
+ if (LLTrans::getString(script_perm.question).empty())
+ {
+ continue;
}
script_question += " " + LLTrans::getString(script_perm.question) + "\n";
}
}
-
+
args["QUESTIONS"] = script_question;
if (known_questions != questions)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index a95636ff23..ac76ad7272 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -107,6 +107,7 @@
#include "llcleanup.h"
#include "llcallstack.h"
#include "llmeshrepository.h"
+#include "llgltfmateriallist.h"
#include "llgl.h"
//#define DEBUG_UPDATE_TYPE
@@ -246,6 +247,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL;
res = NULL; break;
}
+
return res;
}
@@ -259,7 +261,6 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mTEImages(NULL),
mTENormalMaps(NULL),
mTESpecularMaps(NULL),
- mGLName(0),
mbCanSelect(TRUE),
mFlags(0),
mPhysicsShapeType(0),
@@ -343,6 +344,13 @@ LLViewerObject::~LLViewerObject()
{
deleteTEImages();
+ // unhook from reflection probe manager
+ if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe->mViewerObject = nullptr;
+ mReflectionProbe = nullptr;
+ }
+
if(mInventory)
{
mInventory->clear(); // will deref and delete entries
@@ -356,6 +364,13 @@ LLViewerObject::~LLViewerObject()
mPartSourcep = NULL;
}
+ if (mText)
+ {
+ // something recovered LLHUDText when object was already dead
+ mText->markDead();
+ mText = NULL;
+ }
+
// Delete memory associated with extra parameters.
std::map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
@@ -2457,11 +2472,19 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
needs_refresh = needs_refresh || child->mUserSelected;
}
+ static LLCachedControl<bool> allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE);
if (needs_refresh)
{
LLSelectMgr::getInstance()->updateSelectionCenter();
dialog_refresh_all();
- }
+ }
+ else if (allow_select_avatar && asAvatar())
+ {
+ // Override any avatar position updates received
+ // Works only if avatar was repositioned using build
+ // tools and build floater is visible
+ LLSelectMgr::getInstance()->overrideAvatarUpdates();
+ }
// Mark update time as approx. now, with the ping delay.
@@ -3471,11 +3494,11 @@ void LLViewerObject::removeInventory(const LLUUID& item_id)
++mExpectedInventorySerialNum;
}
-bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item)
+bool LLViewerObject::isAssetInInventory(LLViewerInventoryItem* item)
{
bool result = false;
- if (item && LLAssetType::AT_TEXTURE == item->getType())
+ if (item)
{
std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin();
std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end();
@@ -3489,13 +3512,27 @@ bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item)
return result;
}
-void LLViewerObject::updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new)
+void LLViewerObject::updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new)
{
- if (item && !isTextureInInventory(item))
- {
- mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
- updateInventory(item, key, is_new);
- }
+ if (!item)
+ {
+ return;
+ }
+ if (LLAssetType::AT_TEXTURE != item->getType()
+ && LLAssetType::AT_MATERIAL != item->getType())
+ {
+ // Not supported
+ return;
+ }
+
+ if (isAssetInInventory(item))
+ {
+ // already there
+ return;
+ }
+
+ mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
+ updateInventory(item, key, is_new);
}
void LLViewerObject::updateInventory(
@@ -4566,6 +4603,7 @@ BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVecto
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -4852,23 +4890,28 @@ void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID&
}
}
-void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
+
+void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry)
{
- LLUUID old_image_id;
- if (getTE(te))
- {
- old_image_id = getTE(te)->getID();
- }
-
- LLPrimitive::setTE(te, texture_entry);
+ LLUUID old_image_id;
+ if (getTE(te))
+ {
+ old_image_id = getTE(te)->getID();
+ }
- const LLUUID& image_id = getTE(te)->getID();
- LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
- mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ LLPrimitive::setTE(te, texture_entry);
-
- updateAvatarMeshVisibility(image_id,old_image_id);
+ const LLUUID& image_id = getTE(te)->getID();
+ LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
+ mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ updateAvatarMeshVisibility(image_id, old_image_id);
+
+ updateTEMaterialTextures(te);
+}
+void LLViewerObject::updateTEMaterialTextures(U8 te)
+{
if (getTE(te)->getMaterialParams().notNull())
{
const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
@@ -4877,6 +4920,48 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
}
+
+ LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial();
+ LLUUID mat_id = getRenderMaterialID(te);
+ if (mat == nullptr && mat_id.notNull())
+ {
+ mat = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mat_id);
+ getTE(te)->setGLTFMaterial(mat);
+ }
+ else if (mat_id.isNull() && mat != nullptr)
+ {
+ mat = nullptr;
+ getTE(te)->setGLTFMaterial(nullptr);
+ }
+
+ auto fetch_texture = [this](const LLUUID& id)
+ {
+ LLViewerFetchedTexture* img = nullptr;
+ if (id.notNull())
+ {
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
+ {
+ // TODO -- fall back to LLTextureEntry::mGLTFRenderMaterial when overriding with baked texture
+ LLViewerTexture* viewerTexture = getBakedTextureForMagicId(id);
+ img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : nullptr;
+ }
+ else
+ {
+ img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
+ img->addTextureStats(64.f * 64.f, TRUE);
+ }
+ }
+
+ return img;
+ };
+
+ if (mat != nullptr)
+ {
+ mat->mBaseColorTexture = fetch_texture(mat->mBaseColorId);
+ mat->mNormalTexture = fetch_texture(mat->mNormalId);
+ mat->mMetallicRoughnessTexture = fetch_texture(mat->mMetallicRoughnessId);
+ mat->mEmissiveTexture= fetch_texture(mat->mEmissiveId);
+ }
}
void LLViewerObject::refreshBakeTexture()
@@ -5231,10 +5316,42 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
- refreshMaterials();
return retval;
}
+S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat)
+{
+ S32 retval = TEM_CHANGE_NONE;
+
+ LLTextureEntry* tep = getTE(te);
+ if (!tep)
+ { // this could happen if the object is not fully formed yet
+ // returning TEM_CHANGE_NONE here signals to LLGLTFMaterialList to queue the override for later
+ return retval;
+ }
+
+ LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial();
+
+ tep->setGLTFMaterialOverride(override_mat);
+
+ // if override mat exists, we must also have a source mat
+ llassert(override_mat ? bool(src_mat) : true);
+
+ if (override_mat && src_mat)
+ {
+ LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
+ render_mat->applyOverride(*override_mat);
+ tep->setGLTFRenderMaterial(render_mat);
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ else if (tep->setGLTFRenderMaterial(nullptr))
+ {
+ retval = TEM_CHANGE_TEXTURE;
+ }
+
+ return retval;
+}
+
void LLViewerObject::refreshMaterials()
{
setChanged(TEXTURE);
@@ -5417,7 +5534,6 @@ void LLViewerObject::fitFaceTexture(const U8 face)
LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL;
}
-
LLBBox LLViewerObject::getBoundingBoxAgent() const
{
LLVector3 position_agent;
@@ -5502,18 +5618,6 @@ S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
return count;
}
-
-void LLViewerObject::setCanSelect(BOOL canSelect)
-{
- mbCanSelect = canSelect;
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- child->mbCanSelect = canSelect;
- }
-}
-
void LLViewerObject::setDebugText(const std::string &utf8text)
{
if (utf8text.empty() && !mText)
@@ -6017,6 +6121,16 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
new_block = new LLExtendedMeshParams();
break;
}
+ case LLNetworkData::PARAMS_RENDER_MATERIAL:
+ {
+ new_block = new LLRenderMaterialParams();
+ break;
+ }
+ case LLNetworkData::PARAMS_REFLECTION_PROBE:
+ {
+ new_block = new LLReflectionProbeParams();
+ break;
+ }
default:
{
LL_INFOS() << "Unknown param type." << LL_ENDL;
@@ -6160,6 +6274,14 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL
LL_WARNS() << "Failed to send object extra parameters: " << param_type << LL_ENDL;
}
}
+ else
+ {
+ if (param_type == LLNetworkData::PARAMS_RENDER_MATERIAL)
+ {
+ const LLRenderMaterialParams* params = in_use ? (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL) : nullptr;
+ setRenderMaterialIDs(params, local_origin);
+ }
+ }
}
void LLViewerObject::setDrawableState(U32 state, BOOL recursive)
@@ -6958,6 +7080,167 @@ LLVOAvatar* LLViewerObject::getAvatar() const
return NULL;
}
+bool LLViewerObject::hasRenderMaterialParams() const
+{
+ return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL);
+}
+
+void LLViewerObject::setHasRenderMaterialParams(bool has_materials)
+{
+ bool had_materials = hasRenderMaterialParams();
+
+ if (had_materials != has_materials)
+ {
+ if (has_materials)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, true);
+ }
+ else
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true);
+ }
+ }
+}
+
+const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const
+{
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ return param_block->getMaterial(te);
+ }
+
+ return LLUUID::null;
+}
+
+void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id, bool update_server)
+{
+ if (id.notNull())
+ {
+ getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id));
+
+ if (!hasRenderMaterialParams())
+ {
+ // make sure param section exists
+ // but do not update server to avoid race conditions
+ ExtraParameter* param = getExtraParameterEntryCreate(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param)
+ {
+ param->in_use = true;
+ }
+ }
+ }
+ else
+ {
+ getTE(te)->setGLTFMaterial(nullptr);
+ }
+
+ faceMappingChanged();
+ gPipeline.markTextured(mDrawable);
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ param_block->setMaterial(te, id);
+
+ if (param_block->isEmpty())
+ { // might be empty if id is null
+ if (hasRenderMaterialParams())
+ {
+ if (update_server)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true);
+ }
+ else
+ {
+ ExtraParameter* param = getExtraParameterEntryCreate(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param)
+ {
+ param->in_use = false;
+ }
+ }
+ }
+ }
+ else if (update_server)
+ {
+ parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+}
+
+void LLViewerObject::setRenderMaterialIDs(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ if (!hasRenderMaterialParams())
+ {
+ // make sure param section exists
+ // but do not update server to avoid race conditions
+ ExtraParameter* param = getExtraParameterEntryCreate(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param)
+ {
+ param->in_use = true;
+ }
+ }
+ }
+
+ LLRenderMaterialParams* param_block = nullptr;
+ if (hasRenderMaterialParams())
+ {
+ param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ }
+
+ LLGLTFMaterial* material = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id);
+ const S32 num_tes = llmin((S32)getNumTEs(), (S32)getNumFaces());
+
+ for (S32 te = 0; te < num_tes; te++)
+ {
+ getTE(te)->setGLTFMaterial(material);
+
+ if (param_block)
+ {
+ param_block->setMaterial(te, id);
+ }
+ }
+
+ faceMappingChanged();
+ gPipeline.markTextured(mDrawable);
+
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+}
+
+void LLViewerObject::setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin)
+{
+ if (!local_origin)
+ {
+ const S32 num_tes = llmin((S32)getNumTEs(), (S32)getNumFaces()); // avatars have TEs but no faces
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ const LLUUID& id = material_params ? material_params->getMaterial(te) : LLUUID::null;
+ if (id.notNull())
+ {
+ getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id));
+ setHasRenderMaterialParams(true);
+ }
+ else
+ {
+ getTE(te)->setGLTFMaterial(nullptr);
+ }
+ }
+ faceMappingChanged();
+ gPipeline.markTextured(mDrawable);
+ }
+}
class ObjectPhysicsProperties : public LLHTTPNode
{
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index bef8e3e7e3..31e82545ec 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -43,6 +43,7 @@
#include "llvertexbuffer.h"
#include "llbbox.h"
#include "llrigginginfo.h"
+#include "llreflectionmap.h"
class LLAgent; // TODO: Get rid of this.
class LLAudioSource;
@@ -178,6 +179,14 @@ public:
const std::string& getAttachmentItemName() const;
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
+
+ bool hasRenderMaterialParams() const;
+ void setHasRenderMaterialParams(bool has_params);
+
+ const LLUUID& getRenderMaterialID(U8 te) const;
+ void setRenderMaterialID(U8 te, const LLUUID& id, bool update_server = true);
+ void setRenderMaterialIDs(const LLUUID& id);
+
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual BOOL isTempAttachment() const;
@@ -199,6 +208,7 @@ public:
// Graphical stuff for objects - maybe broken out into render class later?
virtual void updateTextures();
+ virtual void faceMappingChanged() {}
virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object
virtual LLDrawable* createDrawable(LLPipeline *pipeline);
@@ -210,6 +220,7 @@ public:
F32 getRotTime() { return mRotTime; }
private:
void resetRotTime();
+ void setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin);
public:
void resetRot();
void applyAngularVelocity(F32 dt);
@@ -238,6 +249,7 @@ public:
virtual BOOL isMesh() const { return FALSE; }
virtual BOOL isRiggedMesh() const { return FALSE; }
virtual BOOL hasLightTexture() const { return FALSE; }
+ virtual BOOL isReflectionProbe() const { return FALSE; }
// This method returns true if the object is over land owned by
// the agent, one of its groups, or it encroaches and
@@ -279,6 +291,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -318,6 +331,7 @@ public:
/*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
+ void updateTEMaterialTextures(U8 te);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
@@ -342,6 +356,7 @@ public:
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
+ virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat);
// Used by Materials update functions to properly kick off rebuilds
// of VBs etc when materials updates require changes.
@@ -356,7 +371,7 @@ public:
LLViewerTexture *getTEImage(const U8 te) const;
LLViewerTexture *getTENormalMap(const U8 te) const;
LLViewerTexture *getTESpecularMap(const U8 te) const;
-
+
bool isImageAlphaBlended(const U8 te) const;
void fitFaceTexture(const U8 face);
@@ -420,8 +435,6 @@ public:
void sendMaterialUpdate() const;
- void setCanSelect(BOOL canSelect);
-
void setDebugText(const std::string &utf8text);
void initHudText();
void restoreHudText();
@@ -472,7 +485,7 @@ public:
// manager until we have better iterators.
void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
- void updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
+ void updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
LLInventoryObject* getInventoryObject(const LLUUID& item_id);
// Get content except for root category
@@ -481,8 +494,6 @@ public:
LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
S16 getInventorySerial() const { return mInventorySerialNum; }
- bool isTextureInInventory(LLViewerInventoryItem* item);
-
// These functions does viewer-side only object inventory modifications
void updateViewerInventoryAsset(
const LLViewerInventoryItem* item,
@@ -611,6 +622,8 @@ public:
std::vector<LLVector3> mUnselectedChildrenPositions ;
private:
+ bool isAssetInInventory(LLViewerInventoryItem* item);
+
ExtraParameter* createNewParameterEntry(U16 param_type);
ExtraParameter* getExtraParameterEntry(U16 param_type) const;
ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
@@ -674,10 +687,10 @@ public:
LLPointer<LLViewerTexture> *mTEImages;
LLPointer<LLViewerTexture> *mTENormalMaps;
LLPointer<LLViewerTexture> *mTESpecularMaps;
-
- // Selection, picking and rendering variables
- U32 mGLName; // GL "name" used by selection code
- BOOL mbCanSelect; // true if user can select this object by clicking
+
+ // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true)
+ // can likely be factored out
+ BOOL mbCanSelect;
private:
// Grabbed from UPDATE_FLAGS
@@ -845,7 +858,7 @@ protected:
F32 mLinksetCost;
F32 mPhysicsCost;
F32 mLinksetPhysicsCost;
-
+
bool mCostStale;
mutable bool mPhysicsShapeUnknown;
@@ -904,6 +917,11 @@ private:
LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
EObjectUpdateType mLastUpdateType;
BOOL mLastUpdateCached;
+
+public:
+ // reflection probe state
+ bool mIsReflectionProbe = false; // if true, this object should register itself with LLReflectionProbeManager
+ LLPointer<LLReflectionMap> mReflectionProbe = nullptr; // reflection probe coupled to this viewer object. If not null, should be deregistered when this object is destroyed
};
///////////////////
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 0e585f13fc..768b4f425b 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -72,7 +72,7 @@
#ifdef LL_USESYSTEMLIBS
#include <zlib.h>
#else
-#include "zlib/zlib.h"
+#include "zlib-ng/zlib.h"
#endif
#include "object_flags.h"
@@ -571,7 +571,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if(update_cache)
{
- objectp = regionp->updateCacheEntry(local_id, objectp, update_type);
+ //update object cache if the object receives a full-update or terse update
+ objectp = regionp->updateCacheEntry(local_id, objectp);
}
// This looks like it will break if the local_id of the object doesn't change
@@ -1339,38 +1340,13 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
}
// Don't clean up mObject references, these will be cleaned up more efficiently later!
- // Also, not cleaned up
- removeDrawable(objectp->mDrawable);
-
+
if(new_dead_object)
{
mNumDeadObjects++;
}
}
-void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
-
- if (!drawablep)
- {
- return;
- }
-
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace* facep = drawablep->getFace(i) ;
- if(facep)
- {
- LLViewerObject* objectp = facep->getViewerObject();
- if(objectp)
- {
- mSelectPickList.erase(objectp);
- }
- }
- }
-}
-
BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
{
// Don't ever kill gAgentAvatarp, just force it to the agent's region
@@ -1836,146 +1812,6 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 &center)
{
}
-void LLViewerObjectList::generatePickList(LLCamera &camera)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
-
- LLViewerObject *objectp;
- S32 i;
- // Reset all of the GL names to zero.
- for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
- {
- (*iter)->mGLName = 0;
- }
-
- mSelectPickList.clear();
-
- std::vector<LLDrawable*> pick_drawables;
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->cull(camera, &pick_drawables, TRUE);
- }
- }
- }
-
- for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin();
- iter != pick_drawables.end(); iter++)
- {
- LLDrawable* drawablep = *iter;
- if( !drawablep )
- continue;
-
- LLViewerObject* last_objectp = NULL;
- for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
- {
- LLFace * facep = drawablep->getFace(face_num);
- if (!facep) continue;
-
- LLViewerObject* objectp = facep->getViewerObject();
-
- if (objectp && objectp != last_objectp)
- {
- mSelectPickList.insert(objectp);
- last_objectp = objectp;
- }
- }
- }
-
- LLHUDNameTag::addPickable(mSelectPickList);
-
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- objectp = (LLVOAvatar*) *iter;
- if (!objectp->isDead())
- {
- if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible())
- {
- mSelectPickList.insert(objectp);
- }
- }
- }
-
- // add all hud objects to pick list
- if (isAgentAvatarValid())
- {
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getIsHUDAttachment())
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- if (LLViewerObject* attached_object = attachment_iter->get())
- {
- mSelectPickList.insert(attached_object);
- LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* childp = *iter;
- if (childp)
- {
- mSelectPickList.insert(childp);
- }
- }
- }
- }
- }
- }
- }
-
- S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances();
-
- if (num_pickables != 0)
- {
- S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables;
-
- std::set<LLViewerObject*>::iterator pick_it;
- i = 0;
- for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();)
- {
- LLViewerObject* objp = (*pick_it);
- if (!objp || objp->isDead() || !objp->mbCanSelect)
- {
- mSelectPickList.erase(pick_it++);
- continue;
- }
-
- objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET;
- i++;
- ++pick_it;
- }
-
- LLHUDIcon::generatePickIDs(i * step, step);
- }
-}
-
-LLViewerObject *LLViewerObjectList::getSelectedObject(const U32 object_id)
-{
- std::set<LLViewerObject*>::iterator pick_it;
- for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end(); ++pick_it)
- {
- if ((*pick_it)->mGLName == object_id)
- {
- return (*pick_it);
- }
- }
- return NULL;
-}
-
void LLViewerObjectList::addDebugBeacon(const LLVector3 &pos_agent,
const std::string &string,
const LLColor4 &color,
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 72b2b99004..f2cba8c259 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -77,7 +77,6 @@ public:
BOOL killObject(LLViewerObject *objectp);
void killObjects(LLViewerRegion *regionp); // Kill all objects owned by a particular region.
void killAllObjects();
- void removeDrawable(LLDrawable* drawablep);
void cleanDeadObjects(const BOOL use_timer = TRUE); // Clean up the dead object list.
@@ -129,11 +128,6 @@ public:
void updateAvatarVisibility();
- // Selection related stuff
- void generatePickList(LLCamera &camera);
-
- LLViewerObject *getSelectedObject(const U32 object_id);
-
inline S32 getNumObjects() { return (S32) mObjects.size(); }
inline S32 getNumActiveObjects() { return (S32) mActiveObjects.size(); }
@@ -226,8 +220,6 @@ protected:
static std::map<U64, LLUUID> sIndexAndLocalIDToUUID;
- std::set<LLViewerObject *> mSelectPickList;
-
friend class LLViewerObject;
private:
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 12624ec3a2..1f16161780 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -800,7 +800,7 @@ U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName()
{
//seed 1024 query names into the free query pool
GLuint queries[1024];
- glGenQueriesARB(1024, queries);
+ glGenQueries(1024, queries);
for (int i = 0; i < 1024; ++i)
{
sFreeQueries.push(queries[i]);
@@ -917,15 +917,12 @@ void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, Octr
void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames()
{
- if (gGLManager.mHasOcclusionQuery)
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
{
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
+ if (mOcclusionQuery[i])
{
- if (mOcclusionQuery[i])
- {
- releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
- }
+ releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
+ mOcclusionQuery[i] = 0;
}
}
}
@@ -948,6 +945,7 @@ void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_M
break;
case STATE_MODE_DIFF:
+ if (mOctreeNode)
{
LLSpatialSetOcclusionStateDiff setter(state);
setter.traverse(mOctreeNode);
@@ -955,6 +953,7 @@ void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_M
break;
case STATE_MODE_BRANCH:
+ if (mOctreeNode)
{
LLSpatialSetOcclusionState setter(state);
setter.traverse(mOctreeNode);
@@ -1024,6 +1023,7 @@ void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE
break;
case STATE_MODE_DIFF:
+ if (mOctreeNode)
{
LLSpatialClearOcclusionStateDiff clearer(state);
clearer.traverse(mOctreeNode);
@@ -1031,6 +1031,7 @@ void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE
break;
case STATE_MODE_BRANCH:
+ if (mOctreeNode)
{
LLSpatialClearOcclusionState clearer(state);
clearer.traverse(mOctreeNode);
@@ -1125,7 +1126,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
GLuint available;
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query available");
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available);
}
if (available)
@@ -1133,7 +1134,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result");
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result);
+ glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT, &query_result);
}
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
@@ -1168,7 +1169,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
{ //check occlusion has been issued for occluded node that has not had a query issued
assert_states_valid(this);
- clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ //clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
assert_states_valid(this);
}
}
@@ -1193,7 +1194,6 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
OCCLUSION_FUDGE_Z = 1.;
}
- // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
if (earlyFail(camera, bounds))
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - early fail");
@@ -1217,17 +1217,12 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
// Depth clamp all water to avoid it being culled as a result of being
// behind the far clip plane, and in the case of edge water to avoid
// it being culled while still visible.
- bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
- (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER ||
+ bool const use_depth_clamp = (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER ||
mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER);
- LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
+ LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
-#if !LL_DARWIN
- U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
-#else
- U32 mode = GL_SAMPLES_PASSED_ARB;
-#endif
+ U32 mode = gGLManager.mGLVersion >= 3.3f ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED;
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
@@ -1246,7 +1241,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
//get an occlusion query that hasn't been used in awhile
releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName();
- glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ glBeginQuery(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
}
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
@@ -1288,7 +1283,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
{
LL_PROFILE_ZONE_NAMED("glEndQuery");
- glEndQueryARB(mode);
+ glEndQuery(mode);
}
}
}
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index e6974b0f84..7666062f99 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -45,11 +45,11 @@ class LLViewerOctreeGroup;
class LLViewerOctreeEntry;
class LLViewerOctreePartition;
-typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener;
-typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
-typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode;
-typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot;
-typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler;
+typedef LLOctreeListener<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeListener;
+typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
+typedef LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeNode;
+typedef LLOctreeRoot<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeRoot;
+typedef LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeTraveler;
#if LL_OCTREE_PARANOIA_CHECK
#define assert_octree_valid(x) x->validate()
@@ -179,7 +179,7 @@ protected:
//defines an octree group for an octree node, which contains multiple entries.
//LL_ALIGN_PREFIX(16)
class LLViewerOctreeGroup
-: public LLOctreeListener<LLViewerOctreeEntry>
+: public OctreeListener
{
LL_ALIGN_NEW
friend class LLViewerOctreeCull;
@@ -198,8 +198,8 @@ public:
};
public:
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter;
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list;
+ typedef OctreeNode::element_iter element_iter;
+ typedef OctreeNode::element_list element_list;
LLViewerOctreeGroup(OctreeNode* node);
LLViewerOctreeGroup(const LLViewerOctreeGroup& rhs)
@@ -245,7 +245,6 @@ public:
const LLVector4a* getObjectExtents() const {return mObjectExtents;}
//octree wrappers to make code more readable
- element_list& getData() { return mOctreeNode->getData(); }
element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index e69b0347f8..75eb16c085 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1553,6 +1553,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
BOOL region_allow_environment_override = true;
S32 parcel_environment_version = 0;
BOOL agent_parcel_update = false; // updating previous(existing) agent parcel
+ U32 extended_flags = 0; //obscure MOAP
S32 other_clean_time = 0;
@@ -1591,6 +1592,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
{
// new agent parcel
+ // *TODO: Does it really make sense to set the agent parcel to this
+ // parcel if the client doesn't know what kind of parcel data this is?
parcel_mgr.mAgentParcelSequenceID = sequence_id;
parcel = parcel_mgr.mAgentParcel;
}
@@ -1642,6 +1645,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override);
}
+ if (msg->getNumberOfBlocks(_PREHASH_ParcelExtendedFlags))
+ {
+ msg->getU32Fast(_PREHASH_ParcelExtendedFlags, _PREHASH_Flags, extended_flags);
+ }
+
if (msg->getNumberOfBlocks(_PREHASH_ParcelEnvironmentBlock))
{
msg->getS32Fast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_ParcelEnvironmentVersion, parcel_environment_version);
@@ -1698,6 +1706,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
parcel->setParcelEnvironmentVersion(cur_parcel_environment_version);
parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override);
+ parcel->setObscureMOAP((bool)extended_flags);
+
parcel->unpackMessage(msg);
if (parcel == parcel_mgr.mAgentParcel)
@@ -1879,8 +1889,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else
{
- // Check for video
- LLViewerParcelMedia::getInstance()->update(parcel);
+ if (gNonInteractive)
+ {
+ return;
+ }
+
+ // Check for video
+ LLViewerParcelMedia::getInstance()->update(parcel);
// Then check for music
if (gAudiop)
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 02f7bbeed8..785c84c38d 100644..100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -264,7 +264,7 @@ BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
- return PARCEL_SOUND_LOCAL & mOwnership[row * mParcelGridsPerEdge + column];
+ return parcelFlags(row, column, PARCEL_SOUND_LOCAL);
}
U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const
@@ -278,12 +278,19 @@ U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
- return parcelLineFlags(row, column);
+ return parcelFlags(row, column, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE);
}
U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const
{
- U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE;
- if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge)
+ return parcelFlags(row, col, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE);
+}
+
+U8 LLViewerParcelOverlay::parcelFlags(S32 row, S32 col, U8 flags) const
+{
+ if (row >= mParcelGridsPerEdge
+ || col >= mParcelGridsPerEdge
+ || row < 0
+ || col < 0)
{
LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL;
return flags;
@@ -908,8 +915,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
// Always fudge a little vertically.
pull_toward_camera.mV[VZ] += 0.01f;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
// Move to appropriate region coords
LLVector3 origin = mRegion->getOriginAgent();
@@ -1014,7 +1021,66 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
}
- gGL.popMatrix();
+ gGL.popMatrix();
return drawn;
}
+
+// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top
+void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom)
+{
+ gGL.begin(LLRender::LINES);
+
+ if (has_left)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(left, top);
+ }
+ if (has_bottom)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(right, bottom);
+ }
+
+ gGL.end();
+}
+
+void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (!mOwnership)
+ {
+ return;
+ }
+ if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ return;
+ }
+
+ LLVector3 origin_agent = mRegion->getOriginAgent();
+ LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
+ F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter;
+ F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter;
+ const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ glLineWidth(1.0f);
+ gGL.color4fv(parcel_outline_color);
+ for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++)
+ {
+ const F32 bottom = region_bottom + (i * map_parcel_width);
+ const F32 top = bottom + map_parcel_width;
+ for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++)
+ {
+ const F32 left = region_left + (j * map_parcel_width);
+ const F32 right = left + map_parcel_width;
+ const bool is_region_boundary = i == GRIDS_PER_EDGE || j == GRIDS_PER_EDGE;
+ const U8 overlay = is_region_boundary ? 0 : mOwnership[(i * GRIDS_PER_EDGE) + j];
+ // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a
+ // 2D map
+ const bool has_left = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE));
+ const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE));
+ grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom);
+ }
+ }
+}
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index e30dbf17b3..c466cc3b6b 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -69,6 +69,7 @@ public:
// Returns the number of vertices drawn
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
U8 ownership( const LLVector3& pos) const;
U8 parcelLineFlags( const LLVector3& pos) const;
@@ -82,12 +83,14 @@ public:
void idleUpdate(bool update_now = false);
void updateGL();
-
+
private:
// This is in parcel rows and columns, not grid rows and columns
// Stored in bottom three bits.
U8 ownership(S32 row, S32 col) const
- { return 0x7 & mOwnership[row * mParcelGridsPerEdge + col]; }
+ { return parcelFlags(row, col, (U8)0x7); }
+
+ U8 parcelFlags(S32 row, S32 col, U8 flags) const;
void addPropertyLine(std::vector<LLVector3>& vertex_array,
std::vector<LLColor4U>& color_array,
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 67ad72e997..36d8fffa7c 100644..100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -95,8 +95,6 @@
// The server only keeps our pending agent info for 60 seconds.
// We want to allow for seed cap retry, but its not useful after that 60 seconds.
-// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
-const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
// Even though we gave up on login, keep trying for caps after we are logged in:
const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
@@ -178,7 +176,6 @@ public:
mCompositionp(NULL),
mEventPoll(NULL),
mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
- mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
mSeedCapAttempts(0),
mHttpResponderID(0),
mLastCameraUpdate(0),
@@ -231,7 +228,6 @@ public:
LLEventPoll* mEventPoll;
S32 mSeedCapMaxAttempts;
- S32 mSeedCapMaxAttemptsBeforeLogin;
S32 mSeedCapAttempts;
S32 mHttpResponderID;
@@ -266,14 +262,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
return;
}
- LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton!
- if (!world_inst)
+ if (!LLWorld::instanceExists())
{
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities, but world no longer exists!" << LL_ENDL;
return;
}
- regionp = world_inst->getRegionFromHandle(regionHandle);
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
@@ -287,19 +282,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
if (url.empty())
{
LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ regionp->setCapabilitiesError();
return; // this error condition is not recoverable.
}
// record that we just entered a new region
newRegionEntry(*regionp);
- // After a few attempts, continue login. But keep trying to get the caps:
- if (impl->mSeedCapAttempts >= impl->mSeedCapMaxAttemptsBeforeLogin &&
- STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
- }
-
if (impl->mSeedCapAttempts > impl->mSeedCapMaxAttempts)
{
// *TODO: Give a user pop-up about this error?
@@ -321,7 +310,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
regionp = NULL;
impl = NULL;
- world_inst = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
if (STATE_WORLD_INIT > LLStartUp::getStartupState())
@@ -332,17 +320,17 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
if (LLApp::isExiting() || gDisconnected)
{
+ LL_DEBUGS("AppInit", "Capabilities") << "Shutting down" << LL_ENDL;
return;
}
- world_inst = LLWorld::getInstance();
- if (!world_inst)
+ if (!LLWorld::instanceExists())
{
LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;
return;
}
- regionp = world_inst->getRegionFromHandle(regionHandle);
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
@@ -351,14 +339,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
impl = regionp->getRegionImplNC();
- ++impl->mSeedCapAttempts;
-
- if (id != impl->mHttpResponderID) // region is no longer referring to this request
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
- // setup for retry.
- continue;
- }
+ ++(impl->mSeedCapAttempts);
if (!result.isMap() || result.has("error"))
{
@@ -379,6 +360,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
// remove the http_result from the llsd
result.erase("http_result");
+ if (id != impl->mHttpResponderID) // region is no longer referring to this request
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
LLSD::map_const_iterator iter;
for (iter = result.beginMap(); iter != result.endMap(); ++iter)
{
@@ -396,11 +384,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
<< " region name " << regionp->getName() << LL_ENDL;
regionp->setCapabilitiesReceived(true);
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
- }
-
break;
}
while (true);
@@ -444,6 +427,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
if (url.empty())
{
LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ if (regionp->getCapability("Seed").empty())
+ {
+ // initial attempt failed to get this cap as well
+ regionp->setCapabilitiesError();
+ }
break; // this error condition is not recoverable.
}
@@ -645,7 +633,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mCacheLoaded(FALSE),
mCacheDirty(FALSE),
mReleaseNotesRequested(FALSE),
- mCapabilitiesReceived(false),
+ mCapabilitiesState(CAPABILITIES_STATE_INIT),
mSimulatorFeaturesReceived(false),
mBitsReceived(0.f),
mPacketsReceived(0.f),
@@ -1080,6 +1068,15 @@ S32 LLViewerRegion::renderPropertyLines()
}
}
+void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (mParcelOverlay)
+ {
+ mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color);
+ }
+}
+
+
// This gets called when the height field changes.
void LLViewerRegion::dirtyHeights()
{
@@ -1245,6 +1242,47 @@ U32 LLViewerRegion::getNumOfVisibleGroups() const
return mImpl ? mImpl->mVisibleGroups.size() : 0;
}
+void LLViewerRegion::updateReflectionProbes()
+{
+#if 1
+ const F32 probe_spacing = 32.f;
+ const F32 probe_radius = sqrtf((probe_spacing * 0.5f) * (probe_spacing * 0.5f) * 3.f);
+ const F32 hover_height = 2.f;
+
+ F32 start = probe_spacing * 0.5f;
+
+ U32 grid_width = REGION_WIDTH_METERS / probe_spacing;
+
+ mReflectionMaps.resize(grid_width * grid_width);
+
+ F32 water_height = getWaterHeight();
+ LLVector3 origin = getOriginAgent();
+
+ for (U32 i = 0; i < grid_width; ++i)
+ {
+ F32 x = i * probe_spacing + start;
+ for (U32 j = 0; j < grid_width; ++j)
+ {
+ F32 y = j * probe_spacing + start;
+
+ U32 idx = i * grid_width + j;
+
+ if (mReflectionMaps[idx].isNull())
+ {
+ mReflectionMaps[idx] = gPipeline.mReflectionMapManager.addProbe();
+ }
+
+ LLVector3 probe_origin = LLVector3(x,y, llmax(water_height, mImpl->mLandp->resolveHeightRegion(x,y)));
+ probe_origin.mV[2] += hover_height;
+ probe_origin += origin;
+
+ mReflectionMaps[idx]->mOrigin.load3(probe_origin.mV);
+ mReflectionMaps[idx]->mRadius = probe_radius;
+ }
+ }
+#endif
+}
+
void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
{
if(!sVOCacheCullingEnabled)
@@ -1820,13 +1858,8 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
//update object cache if the object receives a full-update or terse update
//update_type == EObjectUpdateType::OUT_TERSE_IMPROVED or EObjectUpdateType::OUT_FULL
-LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type)
+LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp)
{
- if(objectp && update_type != (U32)OUT_TERSE_IMPROVED)
- {
- return objectp; //no need to access cache
- }
-
LLVOCacheEntry* entry = getCacheEntry(local_id);
if (!entry)
{
@@ -1838,11 +1871,8 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o
objectp = addNewObject(entry);
}
- //remove from cache if terse update
- if(update_type == (U32)OUT_TERSE_IMPROVED)
- {
- killCacheEntry(entry, true);
- }
+ //remove from cache.
+ killCacheEntry(entry, true);
return objectp;
}
@@ -2302,6 +2332,11 @@ void LLViewerRegion::requestSimulatorFeatures()
std::string coroname =
LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, url, getHandle()));
+
+ // requestSimulatorFeatures can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL;
}
@@ -3002,6 +3037,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("AcceptFriendship");
capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
capabilityNames.append("AgentPreferences");
+ capabilityNames.append("AgentProfile");
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
@@ -3055,11 +3091,13 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
capabilityNames.append("MeshUploadFlag");
+ capabilityNames.append("ModifyMaterialParams");
capabilityNames.append("NavMeshGenerationStatus");
capabilityNames.append("NewFileAgentInventory");
capabilityNames.append("ObjectAnimation");
capabilityNames.append("ObjectMedia");
capabilityNames.append("ObjectMediaNavigate");
+ capabilityNames.append("ObjectNavMeshProperties");
capabilityNames.append("ParcelPropertiesUpdate");
capabilityNames.append("ParcelVoiceInfoRequest");
capabilityNames.append("ProductInfoRequest");
@@ -3095,6 +3133,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("UpdateScriptTask");
capabilityNames.append("UpdateSettingsAgentInventory");
capabilityNames.append("UpdateSettingsTaskInventory");
+ capabilityNames.append("UploadAgentProfileImage");
+ capabilityNames.append("UpdateMaterialAgentInventory");
+ capabilityNames.append("UpdateMaterialTaskInventory");
capabilityNames.append("UploadBakedTexture");
capabilityNames.append("UserInfo");
capabilityNames.append("ViewerAsset");
@@ -3120,6 +3161,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
std::string coroname =
LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle()));
+
+ // setSeedCapability can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
+
return;
}
@@ -3133,6 +3180,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, getHandle()));
+ // setSeedCapability can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
+
LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL;
}
@@ -3254,12 +3306,17 @@ bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const
bool LLViewerRegion::capabilitiesReceived() const
{
- return mCapabilitiesReceived;
+ return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED;
+}
+
+bool LLViewerRegion::capabilitiesError() const
+{
+ return mCapabilitiesState == CAPABILITIES_STATE_ERROR;
}
void LLViewerRegion::setCapabilitiesReceived(bool received)
{
- mCapabilitiesReceived = received;
+ mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT;
// Tell interested parties that we've received capabilities,
// so that they can safely use getCapability().
@@ -3274,6 +3331,11 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
}
}
+void LLViewerRegion::setCapabilitiesError()
+{
+ mCapabilitiesState = CAPABILITIES_STATE_ERROR;
+}
+
boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
{
return mCapabilitiesReceivedSignal.connect(cb);
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index fcbf56c81f..8b27004f1d 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -41,6 +41,7 @@
#include "llcapabilityprovider.h"
#include "m4math.h" // LLMatrix4
#include "llframetimer.h"
+#include "llreflectionmap.h"
// Surface id's
#define LAND 1
@@ -154,6 +155,8 @@ public:
// Draw lines in the dirt showing ownership. Return number of
// vertices drawn.
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
+
// Call this whenever you change the height data in the region.
// (Automatically called by LLSurfacePatch's update routine)
@@ -268,7 +271,9 @@ public:
// has region received its final (not seed) capability list?
bool capabilitiesReceived() const;
+ bool capabilitiesError() const;
void setCapabilitiesReceived(bool received);
+ void setCapabilitiesError();
boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb);
static bool isSpecialCapabilityName(const std::string &name);
@@ -352,7 +357,7 @@ public:
void requestCacheMisses();
void addCacheMissFull(const U32 local_id);
//update object cache if the object receives a full-update or terse update
- LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type);
+ LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp);
void findOrphans(U32 parent_id);
void clearCachedVisibleObjects();
void dumpCache();
@@ -397,6 +402,9 @@ public:
static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
+ // rebuild reflection probe list
+ void updateReflectionProbes();
+
private:
void addToVOCacheTree(LLVOCacheEntry* entry);
LLViewerObject* addNewObject(LLVOCacheEntry* entry);
@@ -527,12 +535,20 @@ private:
BOOL mCacheLoaded;
BOOL mCacheDirty;
BOOL mAlive; // can become false if circuit disconnects
- BOOL mCapabilitiesReceived;
BOOL mSimulatorFeaturesReceived;
BOOL mReleaseNotesRequested;
BOOL mDead; //if true, this region is in the process of deleting.
BOOL mPaused; //pause processing the objects in the region
+ typedef enum
+ {
+ CAPABILITIES_STATE_INIT = 0,
+ CAPABILITIES_STATE_ERROR,
+ CAPABILITIES_STATE_RECEIVED
+ } eCababilitiesState;
+
+ eCababilitiesState mCapabilitiesState;
+
typedef std::map<U32, std::vector<U32> > orphan_list_t;
orphan_list_t mOrphanMap;
@@ -562,6 +578,10 @@ private:
LLFrameTimer mMaterialsCapThrottleTimer;
LLFrameTimer mRenderInfoRequestTimer;
LLFrameTimer mRenderInfoReportTimer;
+
+ // list of reflection maps being managed by this llviewer region
+ std::vector<LLPointer<LLReflectionMap> > mReflectionMaps;
+
};
inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 086b433c72..e1bf1b6e6d 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -49,6 +49,8 @@
#include "lljoint.h"
#include "llskinningutil.h"
+//#pragma optimize("", off)
+
static LLStaticHashedString sTexture0("texture0");
static LLStaticHashedString sTexture1("texture1");
static LLStaticHashedString sTex0("tex0");
@@ -68,13 +70,6 @@ bool LLViewerShaderMgr::sSkipReload = false;
LLVector4 gShinyOrigin;
-//transform shaders
-LLGLSLShader gTransformPositionProgram;
-LLGLSLShader gTransformTexCoordProgram;
-LLGLSLShader gTransformNormalProgram;
-LLGLSLShader gTransformColorProgram;
-LLGLSLShader gTransformTangentProgram;
-
//utility shaders
LLGLSLShader gOcclusionProgram;
LLGLSLShader gSkinnedOcclusionProgram;
@@ -82,6 +77,9 @@ LLGLSLShader gOcclusionCubeProgram;
LLGLSLShader gCustomAlphaProgram;
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gSplatTextureRectProgram;
+LLGLSLShader gReflectionMipProgram;
+LLGLSLShader gRadianceGenProgram;
+LLGLSLShader gIrradianceGenProgram;
LLGLSLShader gGlowCombineFXAAProgram;
LLGLSLShader gTwoTextureAddProgram;
LLGLSLShader gTwoTextureCompareProgram;
@@ -254,10 +252,15 @@ LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightProgram;
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
LLGLSLShader gNormalMapGenProgram;
+LLGLSLShader gDeferredGenBrdfLutProgram;
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
+LLGLSLShader gDeferredPBROpaqueProgram;
+LLGLSLShader gDeferredSkinnedPBROpaqueProgram;
+LLGLSLShader gDeferredPBRAlphaProgram;
+LLGLSLShader gDeferredSkinnedPBRAlphaProgram;
//helper for making a rigged variant of a given shader
bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
@@ -366,7 +369,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
mShaderList.push_back(&gDeferredWLMoonProgram);
- mShaderList.push_back(&gDeferredWLSunProgram);
+ mShaderList.push_back(&gDeferredWLSunProgram);
+ mShaderList.push_back(&gDeferredPBRAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
+
}
LLViewerShaderMgr::~LLViewerShaderMgr()
@@ -434,16 +440,9 @@ void LLViewerShaderMgr::setShaders()
}
static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
- LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1);
-
- //NEVER use more than 16 texture channels (work around for prevalent driver bug)
- LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16);
-
- if (gGLManager.mGLSLVersionMajor < 1 ||
- (gGLManager.mGLSLVersionMajor == 1 && gGLManager.mGLSLVersionMinor <= 20))
- { //NEVER use indexed texture rendering when GLSL version is 1.20 or earlier
- LLGLSLShader::sIndexedTextureChannels = 1;
- }
+
+ // when using indexed texture rendering, leave 8 texture units available for shadow and reflection maps
+ LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-8, (S32) max_texture_index), 1);
reentrance = true;
@@ -457,7 +456,6 @@ void LLViewerShaderMgr::setShaders()
initAttribsAndUniforms();
gPipeline.releaseGLBuffers();
- LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater;
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
LLPipeline::updateRenderDeferred();
@@ -486,11 +484,12 @@ void LLViewerShaderMgr::setShaders()
llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
- bool canRenderDeferred = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
- bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
+ //bool canRenderDeferred = true; // DEPRECATED -- LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
+ //bool hasWindLightShaders = true; // DEPRECATED -- LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
- bool doingWindLight = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- bool useRenderDeferred = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred");
+ bool pbr = gSavedSettings.getBOOL("RenderPBR");
+ bool doingWindLight = true; //DEPRECATED -- hasWindLightShaders&& gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+ bool useRenderDeferred = true; //DEPRECATED -- doingWindLight&& canRenderDeferred&& gSavedSettings.getBOOL("RenderDeferred");
S32 light_class = 3;
S32 interface_class = 2;
@@ -498,15 +497,8 @@ void LLViewerShaderMgr::setShaders()
S32 obj_class = 2;
S32 effect_class = 2;
S32 wl_class = 1;
- S32 water_class = 2;
+ S32 water_class = 3;
S32 deferred_class = 0;
- S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
-
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
- if (!use_transform_feedback)
- {
- transform_class = 0;
- }
if (useRenderDeferred)
{
@@ -528,6 +520,11 @@ void LLViewerShaderMgr::setShaders()
}
}
+ if (deferred_class > 0 && pbr)
+ {
+ deferred_class = 3;
+ }
+
if (doingWindLight)
{
// user has disabled WindLight in their settings, downgrade
@@ -554,17 +551,15 @@ void LLViewerShaderMgr::setShaders()
mShaderLevel[SHADER_EFFECT] = effect_class;
mShaderLevel[SHADER_WINDLIGHT] = wl_class;
mShaderLevel[SHADER_DEFERRED] = deferred_class;
- mShaderLevel[SHADER_TRANSFORM] = transform_class;
- BOOL loaded = loadBasicShaders();
- if (loaded)
+ std::string shader_name = loadBasicShaders();
+ if (shader_name.empty())
{
LL_INFOS() << "Loaded basic shaders." << LL_ENDL;
}
else
{
- LL_ERRS() << "Unable to load basic shaders, verify graphics driver installed and current." << LL_ENDL;
- llassert(loaded);
+ LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL;
reentrance = false; // For hygiene only, re-try probably helps nothing
return;
}
@@ -572,7 +567,7 @@ void LLViewerShaderMgr::setShaders()
gPipeline.mShadersLoaded = true;
// Load all shaders to set max levels
- loaded = loadShadersEnvironment();
+ BOOL loaded = loadShadersEnvironment();
if (loaded)
{
@@ -641,89 +636,31 @@ void LLViewerShaderMgr::setShaders()
}
if (loaded)
-
- {
- loaded = loadTransformShaders();
- if (loaded)
- {
- LL_INFOS() << "Loaded transform shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load transform shaders." << LL_ENDL;
- llassert(loaded);
- }
- }
-
- if (loaded)
{
// Load max avatar shaders to set the max level
mShaderLevel[SHADER_AVATAR] = 3;
mMaxAvatarShaderLevel = 3;
-
- if (loadShadersObject())
- { //hardware skinning is enabled and rigged attachment shaders loaded correctly
- BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+ if (loadShadersObject())
+ { //hardware skinning is enabled and rigged attachment shaders loaded correctly
// cloth is a class3 shader
- S32 avatar_class = avatar_cloth ? 3 : 1;
+ S32 avatar_class = 1;
// Set the actual level
mShaderLevel[SHADER_AVATAR] = avatar_class;
loaded = loadShadersAvatar();
llassert(loaded);
-
- if (mShaderLevel[SHADER_AVATAR] != avatar_class)
- {
- if(llmax(mShaderLevel[SHADER_AVATAR]-1,0) >= 3)
- {
- avatar_cloth = true;
- }
- else
- {
- avatar_cloth = false;
- }
- gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
- }
}
else
{ //hardware skinning not possible, neither is deferred rendering
- mShaderLevel[SHADER_AVATAR] = 0;
- mShaderLevel[SHADER_DEFERRED] = 0;
-
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
-
- loadShadersAvatar(); // unloads
-
- loaded = loadShadersObject();
- llassert(loaded);
+ llassert(false); // SHOULD NOT BE POSSIBLE
}
}
- if (!loaded)
- { //some shader absolutely could not load, try to fall back to a simpler setting
- if (gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
- { //disable windlight and try again
- gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE);
- LL_WARNS() << "Falling back to no windlight shaders." << LL_ENDL;
- reentrance = false;
- setShaders();
- return;
- }
- }
-
llassert(loaded);
-
- if (loaded && !loadShadersDeferred())
- { //everything else succeeded but deferred failed, disable deferred and try again
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- LL_WARNS() << "Falling back to no deferred shaders." << LL_ENDL;
- reentrance = false;
- setShaders();
- return;
- }
+ loaded = loaded && loadShadersDeferred();
+ llassert(loaded);
if (gViewerWindow)
{
@@ -752,6 +689,9 @@ void LLViewerShaderMgr::unloadShaders()
gCustomAlphaProgram.unload();
gGlowCombineProgram.unload();
gSplatTextureRectProgram.unload();
+ gReflectionMipProgram.unload();
+ gRadianceGenProgram.unload();
+ gIrradianceGenProgram.unload();
gGlowCombineFXAAProgram.unload();
gTwoTextureAddProgram.unload();
gTwoTextureCompareProgram.unload();
@@ -840,12 +780,6 @@ void LLViewerShaderMgr::unloadShaders()
gDeferredSkinnedDiffuseProgram.unload();
gDeferredSkinnedBumpProgram.unload();
- gTransformPositionProgram.unload();
- gTransformTexCoordProgram.unload();
- gTransformNormalProgram.unload();
- gTransformColorProgram.unload();
- gTransformTangentProgram.unload();
-
mShaderLevel[SHADER_LIGHTING] = 0;
mShaderLevel[SHADER_OBJECT] = 0;
mShaderLevel[SHADER_AVATAR] = 0;
@@ -854,12 +788,11 @@ void LLViewerShaderMgr::unloadShaders()
mShaderLevel[SHADER_INTERFACE] = 0;
mShaderLevel[SHADER_EFFECT] = 0;
mShaderLevel[SHADER_WINDLIGHT] = 0;
- mShaderLevel[SHADER_TRANSFORM] = 0;
gPipeline.mShadersLoaded = false;
}
-BOOL LLViewerShaderMgr::loadBasicShaders()
+std::string LLViewerShaderMgr::loadBasicShaders()
{
// Load basic dependency shaders first
// All of these have to load for any shaders to function
@@ -908,6 +841,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) );
shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
@@ -942,11 +876,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
for (U32 i = 0; i < shaders.size(); i++)
{
- // Note usage of GL_VERTEX_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)
+ // Note usage of GL_VERTEX_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
{
- LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
- return FALSE;
+ LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
}
}
@@ -958,9 +892,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
{ //use indexed texture rendering for GLSL >= 1.30
- ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
+ ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
}
+ bool has_reflection_probes = gSavedSettings.getS32("RenderReflectionProbeDetail") >= 0 && gGLManager.mGLVersion > 3.99f;
+
std::vector<S32> index_channels;
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
@@ -975,6 +911,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
@@ -1002,19 +939,20 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
for (U32 i = 0; i < shaders.size(); i++)
{
- // Note usage of GL_FRAGMENT_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)
+ // Note usage of GL_FRAGMENT_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0)
{
- LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
- return FALSE;
+ LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
}
}
- return TRUE;
+ return std::string();
}
BOOL LLViewerShaderMgr::loadShadersEnvironment()
{
+#if 1 // DEPRECATED -- forward rendering is deprecated
BOOL success = TRUE;
if (mShaderLevel[SHADER_ENVIRONMENT] == 0)
@@ -1036,8 +974,8 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
gTerrainProgram.mFeatures.disableTextureIndex = true;
gTerrainProgram.mFeatures.hasGamma = true;
gTerrainProgram.mShaderFiles.clear();
- gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER));
+ gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER));
gTerrainProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
success = gTerrainProgram.createShader(NULL, NULL);
llassert(success);
@@ -1050,12 +988,13 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
}
LLWorld::getInstance()->updateWaterObjects();
-
+#endif
return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersWater()
{
+#if 1 // DEPRECATED -- forward rendering is deprecated
BOOL success = TRUE;
BOOL terrainWaterSuccess = TRUE;
@@ -1073,12 +1012,20 @@ BOOL LLViewerShaderMgr::loadShadersWater()
// load water shader
gWaterProgram.mName = "Water Shader";
gWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterProgram.mFeatures.hasAtmospherics = true;
+ gWaterProgram.mFeatures.hasWaterFog = true;
gWaterProgram.mFeatures.hasGamma = true;
gWaterProgram.mFeatures.hasTransport = true;
gWaterProgram.mFeatures.hasSrgb = true;
+ gWaterProgram.mFeatures.hasReflectionProbes = true;
gWaterProgram.mShaderFiles.clear();
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+ gWaterProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
success = gWaterProgram.createShader(NULL, NULL);
@@ -1090,13 +1037,21 @@ BOOL LLViewerShaderMgr::loadShadersWater()
// load water shader
gWaterEdgeProgram.mName = "Water Edge Shader";
gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasWaterFog = true;
gWaterEdgeProgram.mFeatures.hasGamma = true;
gWaterEdgeProgram.mFeatures.hasTransport = true;
gWaterEdgeProgram.mFeatures.hasSrgb = true;
+ gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
gWaterEdgeProgram.mShaderFiles.clear();
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
+ gWaterEdgeProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
success = gWaterEdgeProgram.createShader(NULL, NULL);
@@ -1110,10 +1065,15 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
gUnderWaterProgram.mFeatures.hasWaterFog = true;
gUnderWaterProgram.mShaderFiles.clear();
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gUnderWaterProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gUnderWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
success = gUnderWaterProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -1129,8 +1089,8 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gTerrainWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gTerrainWaterProgram.mFeatures.disableTextureIndex = true;
gTerrainWaterProgram.mShaderFiles.clear();
- gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterV.glsl", GL_VERTEX_SHADER_ARB));
- gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterV.glsl", GL_VERTEX_SHADER));
+ gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER));
gTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
@@ -1168,6 +1128,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
LLWorld::getInstance()->updateWaterObjects();
+#endif
return TRUE;
}
@@ -1188,8 +1149,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
{
gGlowProgram.mName = "Glow Shader (Post)";
gGlowProgram.mShaderFiles.clear();
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER));
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER));
gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
success = gGlowProgram.createShader(NULL, NULL);
if (!success)
@@ -1202,8 +1163,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
{
gGlowExtractProgram.mName = "Glow Extract Shader (Post)";
gGlowExtractProgram.mShaderFiles.clear();
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER));
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER));
gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
success = gGlowExtractProgram.createShader(NULL, NULL);
if (!success)
@@ -1218,7 +1179,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
BOOL LLViewerShaderMgr::loadShadersDeferred()
{
- bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1;
+ bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
+ gSavedSettings.getS32("RenderShadowDetail") > 0;
BOOL ambient_kill = gSavedSettings.getBOOL("AmbientDisable");
BOOL sunlight_kill = gSavedSettings.getBOOL("SunlightDisable");
@@ -1302,11 +1264,19 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredHighlightSpecularProgram.unload();
gNormalMapGenProgram.unload();
+ gDeferredGenBrdfLutProgram.unload();
+
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
gDeferredMaterialProgram[i].unload();
gDeferredMaterialWaterProgram[i].unload();
}
+
+ gDeferredPBROpaqueProgram.unload();
+ gDeferredSkinnedPBROpaqueProgram.unload();
+ gDeferredPBRAlphaProgram.unload();
+ gDeferredSkinnedPBRAlphaProgram.unload();
+
return TRUE;
}
@@ -1316,8 +1286,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredHighlightProgram.mName = "Deferred Highlight Shader";
gDeferredHighlightProgram.mShaderFiles.clear();
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDeferredHighlightProgram.createShader(NULL, NULL);
}
@@ -1326,8 +1296,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredHighlightNormalProgram.mName = "Deferred Highlight Normals Shader";
gDeferredHighlightNormalProgram.mShaderFiles.clear();
- gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
gDeferredHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightNormalProgram.createShader(NULL, NULL);
}
@@ -1336,8 +1306,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredHighlightSpecularProgram.mName = "Deferred Highlight Spec Shader";
gDeferredHighlightSpecularProgram.mShaderFiles.clear();
- gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
gDeferredHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDeferredHighlightSpecularProgram.createShader(NULL, NULL);
}
@@ -1348,8 +1318,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDiffuseProgram.mFeatures.encodesNormal = true;
gDeferredDiffuseProgram.mFeatures.hasSrgb = true;
gDeferredDiffuseProgram.mShaderFiles.clear();
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER));
gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram);
@@ -1361,8 +1331,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";
gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER));
gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram);
@@ -1374,8 +1344,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
@@ -1386,8 +1356,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER));
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
llassert(success);
@@ -1399,8 +1369,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear();
gDeferredNonIndexedDiffuseProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseProgram.mFeatures.hasSrgb = true;
- gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
gDeferredNonIndexedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL);
llassert(success);
@@ -1411,8 +1381,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBumpProgram.mName = "Deferred Bump Shader";
gDeferredBumpProgram.mFeatures.encodesNormal = true;
gDeferredBumpProgram.mShaderFiles.clear();
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER));
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER));
gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram);
success = success && gDeferredBumpProgram.createShader(NULL, NULL);
@@ -1448,8 +1418,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
U32 alpha_mode = i & 0x3;
gDeferredMaterialProgram[i].mShaderFiles.clear();
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMaterialProgram[i].clearPermutations();
@@ -1484,6 +1454,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
if (use_sun_shadow)
{
gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
@@ -1497,7 +1473,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
gDeferredMaterialProgram[i].mFeatures.hasGamma = true;
gDeferredMaterialProgram[i].mFeatures.hasShadows = use_sun_shadow;
-
+ gDeferredMaterialProgram[i].mFeatures.hasReflectionProbes = true;
+
if (has_skin)
{
gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");
@@ -1521,8 +1498,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
gDeferredMaterialWaterProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
@@ -1542,6 +1519,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
if (use_sun_shadow)
{
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
@@ -1573,6 +1556,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialWaterProgram[i].addPermutation("LOCAL_LIGHT_KILL", "1");
}
+ gDeferredMaterialWaterProgram[i].mFeatures.hasReflectionProbes = true;
gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;
gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true;
gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true;
@@ -1611,14 +1595,105 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ if (success)
+ {
+ gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
+ gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true;
+ gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true;
+
+ gDeferredPBROpaqueProgram.mShaderFiles.clear();
+ gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
+ gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredPBROpaqueProgram.addPermutation("HAS_NORMAL_MAP", "1");
+ gDeferredPBROpaqueProgram.addPermutation("HAS_SPECULAR_MAP", "1");
+ gDeferredPBROpaqueProgram.addPermutation("HAS_EMISSIVE_MAP", "1");
+ gDeferredPBROpaqueProgram.addPermutation("DIFFUSE_ALPHA_MODE", "0");
+
+ success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram);
+ if (success)
+ {
+ success = gDeferredPBROpaqueProgram.createShader(NULL, NULL);
+ }
+ llassert(success);
+ }
+
+ if (success)
+ {
+ LLGLSLShader* shader = &gDeferredPBRAlphaProgram;
+ shader->mName = "Deferred PBR Alpha Shader";
+
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.calculatesAtmospherics = true;
+ shader->mFeatures.hasAtmospherics = true;
+ shader->mFeatures.hasGamma = true;
+ shader->mFeatures.hasTransport = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
+ shader->mFeatures.isDeferred = true; // include deferredUtils
+ shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED];
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+
+ U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ shader->addPermutation("HAS_NORMAL_MAP", "1");
+ shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness
+ shader->addPermutation("HAS_EMISSIVE_MAP", "1");
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ if (ambient_kill)
+ {
+ shader->addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ shader->addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ shader->addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram);
+ if (success)
+ {
+ success = shader->createShader(NULL, NULL);
+ }
+ llassert(success);
+
+ // Alpha Shader Hack
+ // See: LLRender::syncMatrices()
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+
+ shader->mRiggedVariant->mFeatures.calculatesLighting = true;
+ shader->mRiggedVariant->mFeatures.hasLighting = true;
+ }
+
if (success)
{
gDeferredTreeProgram.mName = "Deferred Tree Shader";
gDeferredTreeProgram.mShaderFiles.clear();
gDeferredTreeProgram.mFeatures.encodesNormal = true;
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER));
gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTreeProgram.createShader(NULL, NULL);
}
@@ -1629,8 +1704,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTreeShadowProgram.mShaderFiles.clear();
gDeferredTreeShadowProgram.mFeatures.isDeferred = true;
gDeferredTreeShadowProgram.mFeatures.hasShadows = true;
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram;
success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
@@ -1644,8 +1719,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedTreeShadowProgram.mFeatures.isDeferred = true;
gDeferredSkinnedTreeShadowProgram.mFeatures.hasShadows = true;
gDeferredSkinnedTreeShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedTreeShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -1658,8 +1733,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredImpostorProgram.mFeatures.encodesNormal = true;
//gDeferredImpostorProgram.mFeatures.isDeferred = true;
gDeferredImpostorProgram.mShaderFiles.clear();
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER));
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER));
gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredImpostorProgram.createShader(NULL, NULL);
llassert(success);
@@ -1673,8 +1748,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredLightProgram.mFeatures.hasSrgb = true;
gDeferredLightProgram.mShaderFiles.clear();
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredLightProgram.clearPermutations();
@@ -1709,8 +1784,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMultiLightProgram[i].clearPermutations();
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].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
@@ -1743,8 +1818,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSpotLightProgram.mFeatures.hasShadows = true;
gDeferredSpotLightProgram.clearPermutations();
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
if (ambient_kill)
@@ -1775,8 +1850,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMultiSpotLightProgram.clearPermutations();
gDeferredMultiSpotLightProgram.mShaderFiles.clear();
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
if (local_light_kill)
@@ -1815,8 +1890,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSunProgram.mName = "Deferred Sun Shader";
gDeferredSunProgram.mShaderFiles.clear();
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB));
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER));
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER));
gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSunProgram.createShader(NULL, NULL);
@@ -1829,8 +1904,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBlurLightProgram.mFeatures.isDeferred = true;
gDeferredBlurLightProgram.mShaderFiles.clear();
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredBlurLightProgram.createShader(NULL, NULL);
@@ -1867,19 +1942,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mFeatures.hasGamma = true;
shader->mFeatures.hasTransport = true;
shader->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader->mFeatures.hasReflectionProbes = true;
+ shader->mFeatures.hasWaterFog = true;
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader->clearPermutations();
shader->addPermutation("USE_VERTEX_COLOR", "1");
@@ -1887,7 +1956,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->addPermutation("USE_INDEXED_TEX", "1");
if (use_sun_shadow)
{
- shader->addPermutation("HAS_SHADOW", "1");
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
}
if (ambient_kill)
@@ -1943,19 +2012,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mFeatures.isAlphaLighting = true;
shader->mFeatures.encodesNormal = true;
shader->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader->mFeatures.hasReflectionProbes = true;
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader->clearPermutations();
shader->addPermutation("USE_INDEXED_TEX", "1");
@@ -1970,7 +2032,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (use_sun_shadow)
{
- shader->addPermutation("HAS_SHADOW", "1");
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
}
shader->mRiggedVariant = &gDeferredSkinnedAlphaImpostorProgram;
@@ -2014,19 +2076,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader[i]->mFeatures.hasGamma = true;
shader[i]->mFeatures.hasTransport = true;
shader[i]->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader[i]->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader[i]->mFeatures.hasReflectionProbes = true;
+ shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader[i]->mShaderGroup = LLGLSLShader::SG_WATER;
shader[i]->mShaderFiles.clear();
- shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader[i]->clearPermutations();
shader[i]->addPermutation("USE_INDEXED_TEX", "1");
@@ -2035,7 +2090,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader[i]->addPermutation("HAS_ALPHA_MASK", "1");
if (use_sun_shadow)
{
- shader[i]->addPermutation("HAS_SHADOW", "1");
+ shader[i]->addPermutation("HAS_SUN_SHADOW", "1");
}
if (ambient_kill)
@@ -2085,8 +2140,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarEyesProgram.mFeatures.hasShadows = true;
gDeferredAvatarEyesProgram.mShaderFiles.clear();
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);
llassert(success);
@@ -2101,8 +2156,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightProgram.mShaderFiles.clear();
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram);
success = gDeferredFullbrightProgram.createShader(NULL, NULL);
@@ -2118,8 +2173,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram);
@@ -2137,8 +2192,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightWaterProgram.mShaderFiles.clear();
- gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
@@ -2157,8 +2212,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();
- gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
@@ -2176,11 +2231,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true;
gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true;
- gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1;
+ gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightShinyProgram.mShaderFiles.clear();
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram);
success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
llassert(success);
@@ -2194,8 +2250,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredEmissiveProgram.mFeatures.hasTransport = true;
gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredEmissiveProgram.mShaderFiles.clear();
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER));
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER));
gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram);
success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);
@@ -2213,8 +2269,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWaterProgram.mFeatures.hasSrgb = true;
gDeferredWaterProgram.mShaderFiles.clear();
- gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER));
+ gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER));
gDeferredWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gDeferredWaterProgram.createShader(NULL, NULL);
@@ -2234,8 +2290,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
//gDeferredUnderWaterProgram.mFeatures.hasShadows = true;
gDeferredUnderWaterProgram.mShaderFiles.clear();
- gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER));
+ gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER));
gDeferredUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gDeferredUnderWaterProgram.createShader(NULL, NULL);
@@ -2253,13 +2309,19 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenProgram.mFeatures.hasGamma = true;
gDeferredSoftenProgram.mFeatures.isDeferred = true;
gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow;
+ gDeferredSoftenProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
gDeferredSoftenProgram.clearPermutations();
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (use_sun_shadow)
+ {
+ gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
if (ambient_kill)
{
gDeferredSoftenProgram.addPermutation("AMBIENT_KILL", "1");
@@ -2278,6 +2340,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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);
+ gDeferredSoftenProgram.addPermutation("HAS_SSAO", "1");
}
success = gDeferredSoftenProgram.createShader(NULL, NULL);
@@ -2288,8 +2351,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
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.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSoftenWaterProgram.clearPermutations();
gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
@@ -2303,6 +2366,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;
gDeferredSoftenWaterProgram.mFeatures.isDeferred = true;
gDeferredSoftenWaterProgram.mFeatures.hasShadows = use_sun_shadow;
+ gDeferredSoftenWaterProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
+
+ if (use_sun_shadow)
+ {
+ gDeferredSoftenWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
if (ambient_kill)
{
@@ -2317,6 +2386,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (local_light_kill)
{
gDeferredSoftenWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ gDeferredSoftenWaterProgram.addPermutation("HAS_SSAO", "1");
}
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
@@ -2334,13 +2404,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowProgram.mFeatures.isDeferred = true;
gDeferredShadowProgram.mFeatures.hasShadows = true;
gDeferredShadowProgram.mShaderFiles.clear();
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ // gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now
gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
success = gDeferredShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2353,13 +2420,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedShadowProgram.mFeatures.hasShadows = true;
gDeferredSkinnedShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedShadowProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now
success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2370,12 +2434,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowCubeProgram.mFeatures.isDeferred = true;
gDeferredShadowCubeProgram.mFeatures.hasShadows = true;
gDeferredShadowCubeProgram.mShaderFiles.clear();
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
+ // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
llassert(success);
@@ -2387,14 +2448,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations();
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
@@ -2408,14 +2466,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations();
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
@@ -2428,12 +2483,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram;
success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
@@ -2446,12 +2497,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
@@ -2463,12 +2510,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarShadowProgram.mShaderFiles.clear();
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2479,9 +2522,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader";
gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAvatarAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2492,9 +2534,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAvatarAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2506,12 +2547,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2522,9 +2559,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAttachmentAlphaShadowProgram.mName = "Deferred Attachment Alpha Shadow Shader";
gDeferredAttachmentAlphaShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAttachmentAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2535,9 +2571,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAttachmentAlphaMaskShadowProgram.mName = "Deferred Attachment Alpha Mask Shadow Shader";
gDeferredAttachmentAlphaMaskShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAttachmentAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2559,8 +2594,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTerrainProgram.mFeatures.hasTransport = true;
gDeferredTerrainProgram.mShaderFiles.clear();
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTerrainProgram.createShader(NULL, NULL);
llassert(success);
@@ -2582,8 +2617,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTerrainWaterProgram.mFeatures.hasTransport = true;
gDeferredTerrainWaterProgram.mShaderFiles.clear();
- gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1");
@@ -2597,8 +2632,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarProgram.mFeatures.hasSkinning = true;
gDeferredAvatarProgram.mFeatures.encodesNormal = true;
gDeferredAvatarProgram.mShaderFiles.clear();
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarProgram.createShader(NULL, NULL);
llassert(success);
@@ -2620,17 +2655,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
gDeferredAvatarAlphaProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaProgram.clearPermutations();
gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
if (use_sun_shadow)
{
- gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
if (ambient_kill)
@@ -2662,20 +2698,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true;
gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;
gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
llassert(success);
}
- if (success)
+ if (success && gGLManager.mGLVersion > 3.9f)
{
gFXAAProgram.mName = "FXAA Shader";
gFXAAProgram.mFeatures.isDeferred = true;
gFXAAProgram.mShaderFiles.clear();
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB));
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER));
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER));
gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gFXAAProgram.createShader(NULL, NULL);
llassert(success);
@@ -2686,8 +2722,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostProgram.mName = "Deferred Post Shader";
gFXAAProgram.mFeatures.isDeferred = true;
gDeferredPostProgram.mShaderFiles.clear();
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER));
gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostProgram.createShader(NULL, NULL);
llassert(success);
@@ -2698,8 +2734,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredCoFProgram.mName = "Deferred CoF Shader";
gDeferredCoFProgram.mShaderFiles.clear();
gDeferredCoFProgram.mFeatures.isDeferred = true;
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER));
gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredCoFProgram.createShader(NULL, NULL);
llassert(success);
@@ -2710,8 +2746,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader";
gDeferredDoFCombineProgram.mFeatures.isDeferred = true;
gDeferredDoFCombineProgram.mShaderFiles.clear();
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER));
gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredDoFCombineProgram.createShader(NULL, NULL);
llassert(success);
@@ -2722,8 +2758,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostNoDoFProgram.mName = "Deferred Post Shader";
gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;
gDeferredPostNoDoFProgram.mShaderFiles.clear();
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER));
gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
llassert(success);
@@ -2738,8 +2774,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLSkyProgram.mFeatures.hasGamma = true;
gDeferredWLSkyProgram.mFeatures.hasSrgb = true;
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
@@ -2756,8 +2792,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLCloudProgram.mFeatures.hasGamma = true;
gDeferredWLCloudProgram.mFeatures.hasSrgb = true;
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredWLCloudProgram.createShader(NULL, NULL);
@@ -2775,8 +2811,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLSunProgram.mFeatures.disableTextureIndex = true;
gDeferredWLSunProgram.mFeatures.hasSrgb = true;
gDeferredWLSunProgram.mShaderFiles.clear();
- gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredWLSunProgram.createShader(NULL, NULL);
@@ -2795,8 +2831,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLMoonProgram.mFeatures.disableTextureIndex = true;
gDeferredWLMoonProgram.mShaderFiles.clear();
- gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredWLMoonProgram.createShader(NULL, NULL);
@@ -2807,8 +2843,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredStarProgram.mName = "Deferred Star Program";
gDeferredStarProgram.mShaderFiles.clear();
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER));
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER));
gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredStarProgram.createShader(NULL, NULL);
@@ -2819,13 +2855,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gNormalMapGenProgram.mName = "Normal Map Generation Program";
gNormalMapGenProgram.mShaderFiles.clear();
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER_ARB));
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER));
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER));
gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gNormalMapGenProgram.createShader(NULL, NULL);
}
+ if (success)
+ {
+ gDeferredGenBrdfLutProgram.mName = "Brdf Gen Shader";
+ gDeferredGenBrdfLutProgram.mShaderFiles.clear();
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutV.glsl", GL_VERTEX_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL);
+ }
+
+
return success;
}
@@ -2833,7 +2880,83 @@ BOOL LLViewerShaderMgr::loadShadersObject()
{
BOOL success = TRUE;
- if (success)
+ if (success)
+ {
+ gObjectBumpProgram.mName = "Bump Shader";
+ gObjectBumpProgram.mFeatures.encodesNormal = true;
+ gObjectBumpProgram.mShaderFiles.clear();
+ gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER));
+ gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER));
+ gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
+ success = success && gObjectBumpProgram.createShader(NULL, NULL);
+ if (success)
+ { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
+ LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
+ for (int i = 0; i < 2; ++i)
+ {
+ shader[i]->bind();
+ shader[i]->uniform1i(sTexture0, 0);
+ shader[i]->uniform1i(sTexture1, 1);
+ shader[i]->unbind();
+ }
+ }
+ }
+
+ if (success)
+ {
+ gObjectSimpleProgram.mName = "Simple Shader";
+ gObjectSimpleProgram.mFeatures.calculatesLighting = true;
+ gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectSimpleProgram.mFeatures.hasGamma = true;
+ gObjectSimpleProgram.mFeatures.hasAtmospherics = true;
+ gObjectSimpleProgram.mFeatures.hasLighting = true;
+ gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0;
+ gObjectSimpleProgram.mShaderFiles.clear();
+ gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
+ gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectSimpleProgram, gSkinnedObjectSimpleProgram);
+ success = success && gObjectSimpleProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gObjectFullbrightProgram.mName = "Fullbright Shader";
+ gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectFullbrightProgram.mFeatures.hasGamma = true;
+ gObjectFullbrightProgram.mFeatures.hasTransport = true;
+ gObjectFullbrightProgram.mFeatures.isFullbright = true;
+ gObjectFullbrightProgram.mFeatures.hasSrgb = true;
+ gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0;
+ gObjectFullbrightProgram.mShaderFiles.clear();
+ gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectFullbrightProgram, gSkinnedObjectFullbrightProgram);
+ success = success && gObjectFullbrightProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gObjectFullbrightShinyWaterProgram.mName = "Fullbright Shiny Water Shader";
+ gObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;
+ gObjectFullbrightShinyWaterProgram.mShaderFiles.clear();
+ gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER));
+ gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ success = make_rigged_variant(gObjectFullbrightShinyWaterProgram, gSkinnedObjectFullbrightShinyWaterProgram);
+ success = success && gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
{
gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader";
gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesLighting = true;
@@ -2843,8 +2966,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasLighting = true;
gObjectSimpleNonIndexedTexGenProgram.mFeatures.disableTextureIndex = true;
gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.clear();
- gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL);
}
@@ -2859,13 +2982,15 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasLighting = true;
gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.disableTextureIndex = true;
gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.clear();
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleNonIndexedTexGenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectSimpleNonIndexedTexGenWaterProgram.createShader(NULL, NULL);
}
+#if 1 // DEPRECATED -- forward rendering is deprecated
+
if (success)
{
gObjectAlphaMaskNonIndexedProgram.mName = "Non indexed alpha mask Shader";
@@ -2877,8 +3002,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNonIndexedProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNonIndexedProgram.mShaderFiles.clear();
- gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL);
}
@@ -2894,8 +3019,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.clear();
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL);
@@ -2912,8 +3037,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
}
@@ -2929,8 +3054,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNoColorWaterProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear();
- gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL);
@@ -2947,8 +3072,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gTreeProgram.mFeatures.disableTextureIndex = true;
gTreeProgram.mFeatures.hasAlphaMask = true;
gTreeProgram.mShaderFiles.clear();
- gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER));
+ gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gTreeProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gTreeProgram.createShader(NULL, NULL);
}
@@ -2964,8 +3089,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gTreeWaterProgram.mFeatures.disableTextureIndex = true;
gTreeWaterProgram.mFeatures.hasAlphaMask = true;
gTreeWaterProgram.mShaderFiles.clear();
- gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER));
+ gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gTreeWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gTreeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gTreeWaterProgram.createShader(NULL, NULL);
@@ -2981,8 +3106,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNoColorProgram.mFeatures.hasSrgb = true;
gObjectFullbrightNoColorProgram.mFeatures.disableTextureIndex = true;
gObjectFullbrightNoColorProgram.mShaderFiles.clear();
- gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectFullbrightNoColorProgram.createShader(NULL, NULL);
}
@@ -2996,8 +3121,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNoColorWaterProgram.mFeatures.hasTransport = true;
gObjectFullbrightNoColorWaterProgram.mFeatures.disableTextureIndex = true;
gObjectFullbrightNoColorWaterProgram.mShaderFiles.clear();
- gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL);
@@ -3009,8 +3134,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gImpostorProgram.mFeatures.disableTextureIndex = true;
gImpostorProgram.mFeatures.hasSrgb = true;
gImpostorProgram.mShaderFiles.clear();
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER_ARB));
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER));
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER));
gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gImpostorProgram.createShader(NULL, NULL);
}
@@ -3026,8 +3151,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
gObjectPreviewProgram.mShaderFiles.clear();
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER));
gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectPreviewProgram.createShader(NULL, NULL);
gObjectPreviewProgram.mFeatures.hasLighting = true;
@@ -3044,8 +3169,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true;
gPhysicsPreviewProgram.mShaderFiles.clear();
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER_ARB));
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER));
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER));
gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gPhysicsPreviewProgram.createShader(NULL, NULL);
gPhysicsPreviewProgram.mFeatures.hasLighting = false;
@@ -3053,23 +3178,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectSimpleProgram.mName = "Simple Shader";
- gObjectSimpleProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleProgram.mFeatures.hasGamma = true;
- gObjectSimpleProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleProgram.mFeatures.hasLighting = true;
- gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectSimpleProgram.mShaderFiles.clear();
- gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectSimpleProgram, gSkinnedObjectSimpleProgram);
- success = success && gObjectSimpleProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader";
gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true;
gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true;
@@ -3082,8 +3190,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
//
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.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectSimpleImpostorProgram, gSkinnedObjectSimpleImpostorProgram);
success = success && gObjectSimpleImpostorProgram.createShader(NULL, NULL);
@@ -3099,8 +3207,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleWaterProgram.mFeatures.hasLighting = true;
gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectSimpleWaterProgram.mShaderFiles.clear();
- gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
make_rigged_variant(gObjectSimpleWaterProgram, gSkinnedObjectSimpleWaterProgram);
@@ -3109,30 +3217,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectBumpProgram.mName = "Bump Shader";
- gObjectBumpProgram.mFeatures.encodesNormal = true;
- gObjectBumpProgram.mShaderFiles.clear();
- gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
- success = success && gObjectBumpProgram.createShader(NULL, NULL);
- if (success)
- { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
- LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
- for (int i = 0; i < 2; ++i)
- {
- shader[i]->bind();
- shader[i]->uniform1i(sTexture0, 0);
- shader[i]->uniform1i(sTexture1, 1);
- shader[i]->unbind();
- }
- }
- }
-
-
- if (success)
- {
gObjectSimpleAlphaMaskProgram.mName = "Simple Alpha Mask Shader";
gObjectSimpleAlphaMaskProgram.mFeatures.calculatesLighting = true;
gObjectSimpleAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
@@ -3142,8 +3226,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleAlphaMaskProgram.mFeatures.hasAlphaMask = true;
gObjectSimpleAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectSimpleAlphaMaskProgram.mShaderFiles.clear();
- gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectSimpleAlphaMaskProgram, gSkinnedObjectSimpleAlphaMaskProgram);
success = success && gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
@@ -3160,8 +3244,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true;
gObjectSimpleWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.clear();
- gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectSimpleWaterAlphaMaskProgram, gSkinnedObjectSimpleWaterAlphaMaskProgram);
@@ -3170,23 +3254,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectFullbrightProgram.mName = "Fullbright Shader";
- gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightProgram.mFeatures.hasGamma = true;
- gObjectFullbrightProgram.mFeatures.hasTransport = true;
- gObjectFullbrightProgram.mFeatures.isFullbright = true;
- gObjectFullbrightProgram.mFeatures.hasSrgb = true;
- gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightProgram.mShaderFiles.clear();
- gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectFullbrightProgram, gSkinnedObjectFullbrightProgram);
- success = success && gObjectFullbrightProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader";
gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
gObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
@@ -3194,8 +3261,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightWaterProgram.mShaderFiles.clear();
- gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectFullbrightWaterProgram, gSkinnedObjectFullbrightWaterProgram);
@@ -3212,8 +3279,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveProgram.mFeatures.hasSrgb = true;
gObjectEmissiveProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectEmissiveProgram.mShaderFiles.clear();
- gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER));
+ gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectEmissiveProgram, gSkinnedObjectEmissiveProgram);
success = success && gObjectEmissiveProgram.createShader(NULL, NULL);
@@ -3228,8 +3295,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveWaterProgram.mFeatures.hasTransport = true;
gObjectEmissiveWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectEmissiveWaterProgram.mShaderFiles.clear();
- gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER));
+ gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectEmissiveWaterProgram, gSkinnedObjectEmissiveWaterProgram);
@@ -3247,8 +3314,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
gObjectFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectFullbrightAlphaMaskProgram, gSkinnedObjectFullbrightAlphaMaskProgram);
success = success && gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);
@@ -3264,8 +3331,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true;
gObjectFullbrightWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.clear();
- gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectFullbrightWaterAlphaMaskProgram, gSkinnedObjectFullbrightWaterAlphaMaskProgram);
@@ -3282,8 +3349,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyProgram.mFeatures.isShiny = true;
gObjectShinyProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectShinyProgram.mShaderFiles.clear();
- gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER));
+ gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER));
gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectShinyProgram, gSkinnedObjectShinyProgram);
success = success && gObjectShinyProgram.createShader(NULL, NULL);
@@ -3299,8 +3366,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true;
gObjectShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectShinyWaterProgram.mShaderFiles.clear();
- gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
+ gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER));
+ gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER));
gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectShinyWaterProgram, gSkinnedObjectShinyWaterProgram);
@@ -3317,43 +3384,27 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyProgram.mFeatures.hasTransport = true;
gObjectFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightShinyProgram.mShaderFiles.clear();
- gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectFullbrightShinyProgram, gSkinnedObjectFullbrightShinyProgram);
success = success && gObjectFullbrightShinyProgram.createShader(NULL, NULL);
}
- if (success)
- {
- gObjectFullbrightShinyWaterProgram.mName = "Fullbright Shiny Water Shader";
- gObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightShinyWaterProgram.mShaderFiles.clear();
- gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = make_rigged_variant(gObjectFullbrightShinyWaterProgram, gSkinnedObjectFullbrightShinyWaterProgram);
- success = success && gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
- }
+#endif
+
+ if (!success)
+ {
+ mShaderLevel[SHADER_OBJECT] = 0;
+ return FALSE;
+ }
- if( !success )
- {
- mShaderLevel[SHADER_OBJECT] = 0;
- return FALSE;
- }
-
return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersAvatar()
{
+#if 1 // DEPRECATED -- forward rendering is deprecated
BOOL success = TRUE;
if (mShaderLevel[SHADER_AVATAR] == 0)
@@ -3377,8 +3428,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarProgram.mFeatures.hasAlphaMask = true;
gAvatarProgram.mFeatures.disableTextureIndex = true;
gAvatarProgram.mShaderFiles.clear();
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER));
gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarProgram.createShader(NULL, NULL);
@@ -3394,8 +3445,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarWaterProgram.mFeatures.hasAlphaMask = true;
gAvatarWaterProgram.mFeatures.disableTextureIndex = true;
gAvatarWaterProgram.mShaderFiles.clear();
- gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
// Note: no cloth under water:
gAvatarWaterProgram.mShaderLevel = llmin(mShaderLevel[SHADER_AVATAR], 1);
gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
@@ -3415,8 +3466,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarPickProgram.mFeatures.hasSkinning = true;
gAvatarPickProgram.mFeatures.disableTextureIndex = true;
gAvatarPickProgram.mShaderFiles.clear();
- gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER));
gAvatarPickProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarPickProgram.createShader(NULL, NULL);
}
@@ -3433,8 +3484,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarEyeballProgram.mFeatures.hasAlphaMask = true;
gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;
gAvatarEyeballProgram.mShaderFiles.clear();
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER));
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER));
gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarEyeballProgram.createShader(NULL, NULL);
}
@@ -3445,7 +3496,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
mMaxAvatarShaderLevel = 0;
return FALSE;
}
-
+#endif
return TRUE;
}
@@ -3457,8 +3508,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gHighlightProgram.mName = "Highlight Shader";
gHighlightProgram.mShaderFiles.clear();
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram);
success = success && gHighlightProgram.createShader(NULL, NULL);
@@ -3468,8 +3519,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gHighlightNormalProgram.mName = "Highlight Normals Shader";
gHighlightNormalProgram.mShaderFiles.clear();
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightNormalProgram.createShader(NULL, NULL);
}
@@ -3478,8 +3529,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gHighlightSpecularProgram.mName = "Highlight Spec Shader";
gHighlightSpecularProgram.mShaderFiles.clear();
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightSpecularProgram.createShader(NULL, NULL);
}
@@ -3488,8 +3539,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gUIProgram.mName = "UI Shader";
gUIProgram.mShaderFiles.clear();
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB));
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER));
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER));
gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gUIProgram.createShader(NULL, NULL);
}
@@ -3498,8 +3549,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gPathfindingProgram.mName = "Pathfinding Shader";
gPathfindingProgram.mShaderFiles.clear();
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER_ARB));
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gPathfindingProgram.createShader(NULL, NULL);
}
@@ -3508,8 +3559,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader";
gPathfindingNoNormalsProgram.mShaderFiles.clear();
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER_ARB));
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
}
@@ -3518,8 +3569,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gCustomAlphaProgram.mName = "Custom Alpha Shader";
gCustomAlphaProgram.mShaderFiles.clear();
- gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB));
- gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER));
+ gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER));
gCustomAlphaProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gCustomAlphaProgram.createShader(NULL, NULL);
}
@@ -3528,8 +3579,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gSplatTextureRectProgram.mName = "Splat Texture Rect Shader";
gSplatTextureRectProgram.mShaderFiles.clear();
- gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER_ARB));
- gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
+ gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER));
gSplatTextureRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSplatTextureRectProgram.createShader(NULL, NULL);
if (success)
@@ -3544,8 +3595,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gGlowCombineProgram.mName = "Glow Combine Shader";
gGlowCombineProgram.mShaderFiles.clear();
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER));
gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGlowCombineProgram.createShader(NULL, NULL);
if (success)
@@ -3561,8 +3612,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader";
gGlowCombineFXAAProgram.mShaderFiles.clear();
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER));
gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
if (success)
@@ -3574,13 +3625,12 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
}
}
-
if (success)
{
gTwoTextureAddProgram.mName = "Two Texture Add Shader";
gTwoTextureAddProgram.mShaderFiles.clear();
- gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER_ARB));
- gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER));
+ gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER));
gTwoTextureAddProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gTwoTextureAddProgram.createShader(NULL, NULL);
if (success)
@@ -3596,8 +3646,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
gTwoTextureCompareProgram.mShaderFiles.clear();
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB));
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER));
gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gTwoTextureCompareProgram.createShader(NULL, NULL);
if (success)
@@ -3613,8 +3663,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOneTextureFilterProgram.mName = "One Texture Filter Shader";
gOneTextureFilterProgram.mShaderFiles.clear();
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB));
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER));
gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOneTextureFilterProgram.createShader(NULL, NULL);
if (success)
@@ -3629,8 +3679,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOneTextureNoColorProgram.mName = "One Texture No Color Shader";
gOneTextureNoColorProgram.mShaderFiles.clear();
- gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB));
- gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER));
+ gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER));
gOneTextureNoColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOneTextureNoColorProgram.createShader(NULL, NULL);
if (success)
@@ -3644,8 +3694,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gSolidColorProgram.mName = "Solid Color Shader";
gSolidColorProgram.mShaderFiles.clear();
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER_ARB));
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER));
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER));
gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSolidColorProgram.createShader(NULL, NULL);
if (success)
@@ -3660,8 +3710,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOcclusionProgram.mName = "Occlusion Shader";
gOcclusionProgram.mShaderFiles.clear();
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB));
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER));
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram;
success = gOcclusionProgram.createShader(NULL, NULL);
@@ -3672,8 +3722,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gSkinnedOcclusionProgram.mName = "Skinned Occlusion Shader";
gSkinnedOcclusionProgram.mFeatures.hasObjectSkinning = true;
gSkinnedOcclusionProgram.mShaderFiles.clear();
- gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER));
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gSkinnedOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSkinnedOcclusionProgram.createShader(NULL, NULL);
}
@@ -3682,8 +3732,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
gOcclusionCubeProgram.mShaderFiles.clear();
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB));
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOcclusionCubeProgram.createShader(NULL, NULL);
}
@@ -3692,8 +3742,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gDebugProgram.mName = "Debug Shader";
gDebugProgram.mShaderFiles.clear();
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER));
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER));
gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram;
gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram);
@@ -3704,8 +3754,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gClipProgram.mName = "Clip Shader";
gClipProgram.mShaderFiles.clear();
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB));
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER));
gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gClipProgram.createShader(NULL, NULL);
}
@@ -3714,8 +3764,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gDownsampleDepthProgram.mName = "DownsampleDepth Shader";
gDownsampleDepthProgram.mShaderFiles.clear();
- gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
- gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER));
+ gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER));
gDownsampleDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDownsampleDepthProgram.createShader(NULL, NULL);
}
@@ -3724,8 +3774,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gBenchmarkProgram.mName = "Benchmark Shader";
gBenchmarkProgram.mShaderFiles.clear();
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB));
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gBenchmarkProgram.createShader(NULL, NULL);
}
@@ -3734,8 +3784,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader";
gDownsampleDepthRectProgram.mShaderFiles.clear();
- gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
- gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER));
+ gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER));
gDownsampleDepthRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
}
@@ -3744,12 +3794,49 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gAlphaMaskProgram.mName = "Alpha Mask Shader";
gAlphaMaskProgram.mShaderFiles.clear();
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER));
gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gAlphaMaskProgram.createShader(NULL, NULL);
}
+ if (success)
+ {
+ gReflectionMipProgram.mName = "Reflection Mip Shader";
+ gReflectionMipProgram.mFeatures.isDeferred = true;
+ gReflectionMipProgram.mShaderFiles.clear();
+ gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
+ gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER));
+ gReflectionMipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gReflectionMipProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gReflectionMipProgram.bind();
+ gReflectionMipProgram.uniform1i(sScreenMap, 0);
+ gReflectionMipProgram.unbind();
+ }
+ }
+
+ if (success && gGLManager.mHasCubeMapArray)
+ {
+ gRadianceGenProgram.mName = "Radiance Gen Shader";
+ gRadianceGenProgram.mShaderFiles.clear();
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER));
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gRadianceGenProgram.createShader(NULL, NULL);
+ }
+
+ if (success && gGLManager.mHasCubeMapArray)
+ {
+ gIrradianceGenProgram.mName = "Irradiance Gen Shader";
+ gIrradianceGenProgram.mShaderFiles.clear();
+ gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenV.glsl", GL_VERTEX_SHADER));
+ gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gIrradianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gIrradianceGenProgram.createShader(NULL, NULL);
+ }
+
if( !success )
{
mShaderLevel[SHADER_INTERFACE] = 0;
@@ -3762,7 +3849,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
BOOL LLViewerShaderMgr::loadShadersWindLight()
{
BOOL success = TRUE;
-
+#if 1 // DEPRECATED -- forward rendering is deprecated
if (mShaderLevel[SHADER_WINDLIGHT] < 2)
{
gWLSkyProgram.unload();
@@ -3780,8 +3867,8 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLSkyProgram.mFeatures.hasTransport = true;
gWLSkyProgram.mFeatures.hasGamma = true;
gWLSkyProgram.mFeatures.hasSrgb = true;
- gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER_ARB));
- gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER));
+ gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER));
gWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gWLSkyProgram.createShader(NULL, NULL);
@@ -3795,8 +3882,8 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLCloudProgram.mFeatures.hasTransport = true;
gWLCloudProgram.mFeatures.hasGamma = true;
gWLCloudProgram.mFeatures.hasSrgb = true;
- gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER_ARB));
- gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER));
+ gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER));
gWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gWLCloudProgram.createShader(NULL, NULL);
@@ -3813,8 +3900,8 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLSunProgram.mFeatures.isFullbright = true;
gWLSunProgram.mFeatures.disableTextureIndex = true;
gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscV.glsl", GL_VERTEX_SHADER_ARB));
- gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscV.glsl", GL_VERTEX_SHADER));
+ gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscF.glsl", GL_FRAGMENT_SHADER));
gWLSunProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gWLSunProgram.createShader(NULL, NULL);
@@ -3831,102 +3918,13 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLMoonProgram.mFeatures.isFullbright = true;
gWLMoonProgram.mFeatures.disableTextureIndex = true;
gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonV.glsl", GL_VERTEX_SHADER_ARB));
- gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonV.glsl", GL_VERTEX_SHADER));
+ gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonF.glsl", GL_FRAGMENT_SHADER));
gWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gWLMoonProgram.createShader(NULL, NULL);
}
-
- return success;
-}
-
-BOOL LLViewerShaderMgr::loadTransformShaders()
-{
- BOOL success = TRUE;
-
- if (mShaderLevel[SHADER_TRANSFORM] < 1)
- {
- gTransformPositionProgram.unload();
- gTransformTexCoordProgram.unload();
- gTransformNormalProgram.unload();
- gTransformColorProgram.unload();
- gTransformTangentProgram.unload();
- return TRUE;
- }
-
- if (success)
- {
- gTransformPositionProgram.mName = "Position Transform Shader";
- gTransformPositionProgram.mShaderFiles.clear();
- gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "position_out",
- "texture_index_out",
- };
-
- success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings);
- }
-
- if (success)
- {
- gTransformTexCoordProgram.mName = "TexCoord Transform Shader";
- gTransformTexCoordProgram.mShaderFiles.clear();
- gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "texcoord_out",
- };
-
- success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
- {
- gTransformNormalProgram.mName = "Normal Transform Shader";
- gTransformNormalProgram.mShaderFiles.clear();
- gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "normal_out",
- };
-
- success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
- {
- gTransformColorProgram.mName = "Color Transform Shader";
- gTransformColorProgram.mShaderFiles.clear();
- gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "color_out",
- };
-
- success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
- {
- gTransformTangentProgram.mName = "Binormal Transform Shader";
- gTransformTangentProgram.mShaderFiles.clear();
- gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "tangent_out",
- };
-
- success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);
- }
-
-
+#endif
return success;
}
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 93bb29a355..a2ae984caa 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -49,7 +49,11 @@ public:
void setShaders();
void unloadShaders();
S32 getShaderLevel(S32 type);
- BOOL loadBasicShaders();
+
+ // loadBasicShaders in case of a failure returns
+ // name of a file error happened at, otherwise
+ // returns an empty string
+ std::string loadBasicShaders();
BOOL loadShadersEffects();
BOOL loadShadersDeferred();
BOOL loadShadersObject();
@@ -58,7 +62,6 @@ public:
BOOL loadShadersWater();
BOOL loadShadersInterface();
BOOL loadShadersWindLight();
- BOOL loadTransformShaders();
std::vector<S32> mShaderLevel;
S32 mMaxAvatarShaderLevel;
@@ -74,7 +77,6 @@ public:
SHADER_WINDLIGHT,
SHADER_WATER,
SHADER_DEFERRED,
- SHADER_TRANSFORM,
SHADER_COUNT
};
@@ -146,21 +148,15 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade
extern LLVector4 gShinyOrigin;
-//transform shaders
-extern LLGLSLShader gTransformPositionProgram;
-extern LLGLSLShader gTransformTexCoordProgram;
-extern LLGLSLShader gTransformNormalProgram;
-extern LLGLSLShader gTransformColorProgram;
-extern LLGLSLShader gTransformTangentProgram;
-
-
-
//utility shaders
extern LLGLSLShader gOcclusionProgram;
extern LLGLSLShader gOcclusionCubeProgram;
extern LLGLSLShader gCustomAlphaProgram;
extern LLGLSLShader gGlowCombineProgram;
extern LLGLSLShader gSplatTextureRectProgram;
+extern LLGLSLShader gReflectionMipProgram;
+extern LLGLSLShader gRadianceGenProgram;
+extern LLGLSLShader gIrradianceGenProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;
extern LLGLSLShader gDebugProgram;
extern LLGLSLShader gClipProgram;
@@ -309,8 +305,12 @@ extern LLGLSLShader gDeferredWLMoonProgram;
extern LLGLSLShader gDeferredStarProgram;
extern LLGLSLShader gDeferredFullbrightShinyProgram;
extern LLGLSLShader gNormalMapGenProgram;
+extern LLGLSLShader gDeferredGenBrdfLutProgram;
// Deferred materials shaders
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
+
+extern LLGLSLShader gDeferredPBROpaqueProgram;
+extern LLGLSLShader gDeferredPBRAlphaProgram;
#endif
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 57d52ae9ee..5d936dfc90 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -488,7 +488,9 @@ void send_viewer_stats(bool include_preferences)
system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value();
system["os"] = LLOSInfo::instance().getOSStringSimple();
system["cpu"] = gSysCPU.getCPUString();
+ system["cpu_sse"] = gSysCPU.getSSEVersions();
system["address_size"] = ADDRESS_SIZE;
+ system["os_bitness"] = LLOSInfo::instance().getOSBitness();
unsigned char MACAddress[MAC_ADDRESS_BYTES];
LLUUID::getNodeID(MACAddress);
std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index e2de7ac825..3f302d4f45 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -42,6 +42,7 @@
#include "lllandmark.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
+#include "llmaterialeditor.h"
#include "llmemorystream.h"
#include "llmenugl.h"
#include "llnotecard.h"
@@ -542,6 +543,7 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break;
case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break;
case LLAssetType::AT_SETTINGS: img_name = "Inv_Settings"; break;
+ case LLAssetType::AT_MATERIAL: img_name = "Inv_Material"; break;
default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981)
}
@@ -879,6 +881,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_MESH:
+ case DAD_MATERIAL:
{
supported = true;
break;
@@ -1126,6 +1129,9 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwch
case LLAssetType::AT_SETTINGS:
openEmbeddedSetting(item, wc);
return TRUE;
+ case LLAssetType::AT_MATERIAL:
+ openEmbeddedGLTFMaterial(item, wc);
+ return TRUE;
case LLAssetType::AT_NOTECARD:
case LLAssetType::AT_LSL_TEXT:
case LLAssetType::AT_CLOTHING:
@@ -1212,6 +1218,26 @@ void LLViewerTextEditor::openEmbeddedSetting(LLInventoryItem* item, llwchar wc)
}
}
+void LLViewerTextEditor::openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc)
+{
+ if (!item)
+ {
+ return;
+ }
+
+ LLSD floater_key;
+ floater_key["objectid"] = mObjectID;
+ floater_key["notecardid"] = mNotecardInventoryID;
+ LLMaterialEditor* preview = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (preview)
+ {
+ preview->setAuxItem(item);
+ preview->setNotecardInfo(mNotecardInventoryID, mObjectID);
+ preview->openFloater(floater_key);
+ preview->setFocus(TRUE);
+ }
+}
+
void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item )
{
LLSD payload;
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index a6d7fef409..6170d476b8 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -108,6 +108,7 @@ private:
void openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );
void openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);
void openEmbeddedSetting(LLInventoryItem* item, llwchar wc);
+ void openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc);
void showCopyToInvDialog( LLInventoryItem* item, llwchar wc );
void showUnsavedAlertDialog( LLInventoryItem* item );
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 3584fffd44..590f24d359 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -76,9 +76,10 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultIrradiancePBRp;
LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap;
LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL;
-F32 LLViewerFetchedTexture::sMaxVirtualSize = F32_MAX/2.f;
+F32 LLViewerFetchedTexture::sMaxVirtualSize = 8192.f*8192.f;
const std::string sTesterName("TextureTester");
@@ -99,7 +100,6 @@ U32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
U32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
bool LLViewerTexture::sFreezeImageUpdates = false;
F32 LLViewerTexture::sCurrentTime = 0.0f;
-F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
@@ -286,6 +286,13 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
return tex;
}
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps)
+{
+ LLViewerFetchedTexture* ret = new LLViewerFetchedTexture(raw, type, usemipmaps);
+ gTextureList.addImage(ret, TEX_LIST_STANDARD);
+ return ret;
+}
+
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
const LLUUID &image_id,
FTType f_type,
@@ -451,6 +458,7 @@ void LLViewerTextureManager::cleanup()
LLViewerFetchedTexture::sWhiteImagep = NULL;
LLViewerFetchedTexture::sFlatNormalImagep = NULL;
+ LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL;
LLViewerMediaTexture::cleanUpClass();
}
@@ -802,7 +810,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
mNeedsGLTexture = TRUE;
}
- virtual_size *= sTexelPixelRatio;
+ virtual_size = llmin(virtual_size, LLViewerFetchedTexture::sMaxVirtualSize);
if (virtual_size > mMaxVirtualSize)
{
@@ -1905,8 +1913,7 @@ bool LLViewerFetchedTexture::updateFetch()
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2);
static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3);
- if(textures_decode_disabled ||
- (gUseWireframe && mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED_SELF)) // don't fetch the surface textures in wireframe mode
+ if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode
{
return false;
}
@@ -2052,7 +2059,7 @@ bool LLViewerFetchedTexture::updateFetch()
if (!mIsFetching)
{
- if ((decode_priority > 0) && (mRawDiscardLevel < 0))
+ if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL))
{
// We finished but received no data
if (getDiscardLevel() < 0)
@@ -2107,7 +2114,7 @@ bool LLViewerFetchedTexture::updateFetch()
desired_discard = llmin(desired_discard, getMaxDiscardLevel());
bool make_request = true;
- /*if (decode_priority <= 0)
+ if (decode_priority <= 0)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0");
make_request = false;
@@ -2117,7 +2124,7 @@ bool LLViewerFetchedTexture::updateFetch()
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max");
make_request = false;
}
- else */ if (mNeedsCreateTexture || mIsMissingAsset)
+ else if (mNeedsCreateTexture || mIsMissingAsset)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing");
make_request = false;
@@ -2198,16 +2205,18 @@ bool LLViewerFetchedTexture::updateFetch()
}
// bypass texturefetch directly by pulling from LLTextureCache
- bool fetch_request_created = false;
- fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
+ S32 fetch_request_discard = -1;
+ fetch_request_discard = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
w, h, c, desired_discard, needsAux(), mCanUseHTTP);
- if (fetch_request_created)
+ if (fetch_request_discard >= 0)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");
mHasFetcher = TRUE;
mIsFetching = TRUE;
- mRequestedDiscardLevel = desired_discard;
+ // in some cases createRequest can modify discard, as an example
+ // bake textures are always at discard 0
+ mRequestedDiscardLevel = llmin(desired_discard, fetch_request_discard);
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 8c41c4a6bc..312e2ca365 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -218,7 +218,6 @@ protected:
LL::WorkQueue::weak_t mMainQueue;
LL::WorkQueue::weak_t mImageQueue;
- static F32 sTexelPixelRatio;
public:
static const U32 sCurrentFileVersion;
static S32 sImageCount;
@@ -531,6 +530,7 @@ public:
static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture
static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface
+ static LLPointer<LLViewerFetchedTexture> sDefaultIrradiancePBRp; // PBR: irradiance
};
//
@@ -660,6 +660,8 @@ public:
static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
+ static LLViewerFetchedTexture* getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps);
+
static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,
FTType f_type = FTT_DEFAULT,
BOOL usemipmap = TRUE,
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 8faeb70553..55a735e906 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -50,6 +50,7 @@
#include "llviewercontrol.h"
#include "llviewertexture.h"
#include "llviewermedia.h"
+#include "llviewernetwork.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "pipeline.h"
@@ -120,7 +121,10 @@ void LLViewerTextureList::doPreloadImages()
// Set the default flat normal map
LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP);
-
+
+ // PBR: irradiance
+ LLViewerFetchedTexture::sDefaultIrradiancePBRp = LLViewerTextureManager::getFetchedTextureFromFile("default_irradiance.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+
image_list->initFromFile();
// turn off clamping and bilinear filtering for uv picking images
@@ -152,12 +156,6 @@ void LLViewerTextureList::doPreloadImages()
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
- image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
- if (image)
- {
- image->setAddressMode(LLTexUnit::TAM_WRAP);
- mImagePreloads.insert(image);
- }
image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
0, 0, IMG_TRANSPARENT);
if (image)
@@ -190,13 +188,31 @@ void LLViewerTextureList::doPreloadImages()
static std::string get_texture_list_name()
{
- return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
+ if (LLGridManager::getInstance()->isInProductionGrid())
+ {
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
+ "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
+ }
+ else
+ {
+ const std::string& grid_id_str = LLGridManager::getInstance()->getGridId();
+ const std::string& grid_id_lower = utf8str_tolower(grid_id_str);
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
+ "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + "." + grid_id_lower + ".xml");
+ }
}
void LLViewerTextureList::doPrefetchImages()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+ if (imagep)
+ {
+ imagep->setAddressMode(LLTexUnit::TAM_WRAP);
+ mImagePreloads.insert(imagep);
+ }
+
if (LLAppViewer::instance()->getPurgeCache())
{
// cache was purged, no point
@@ -1166,14 +1182,15 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
- const U8 codec)
+ const U8 codec,
+ const S32 max_image_dimentions)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
{
- image->setLastError("Couldn't open the image to be uploaded.");
+ LL_WARNS() << "Couldn't open the image to be uploaded." << LL_ENDL;
return FALSE;
}
if (!image->load(filename))
@@ -1195,7 +1212,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
return FALSE;
}
// Convert to j2c (JPEG2000) and save the file locally
- LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
+ LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions);
if (compressedImage.isNull())
{
image->setLastError("Couldn't convert the image to jpeg2000.");
@@ -1220,15 +1237,18 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
}
// note: modifies the argument raw_image!!!!
-LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image)
+LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions, bool force_lossless)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
- if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
- (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
- compressedImage->setReversible(TRUE);
+ if (force_lossless ||
+ (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
+ (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)))
+ {
+ compressedImage->setReversible(TRUE);
+ }
if (gSavedSettings.getBOOL("Jpeg2000AdvancedCompression"))
@@ -1255,152 +1275,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
///////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data)
-{
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
-
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-
- // Receive image header, copy into image object and decompresses
- // if this is a one-packet image.
-
- LLUUID id;
-
- char ip_string[256];
- u32_to_ip_string(msg->getSenderIP(),ip_string);
-
- U32Bytes received_size ;
- if (msg->getReceiveCompressedSize())
- {
- received_size = (U32Bytes)msg->getReceiveCompressedSize() ;
- }
- else
- {
- received_size = (U32Bytes)msg->getReceiveSize() ;
- }
- add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, received_size);
- add(LLStatViewer::TEXTURE_PACKETS, 1);
-
- U8 codec;
- U16 packets;
- U32 totalbytes;
- msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
- msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec);
- msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets);
- msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes);
-
- S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
- if (!data_size)
- {
- return;
- }
- if (data_size < 0)
- {
- // msg->getSizeFast() is probably trying to tell us there
- // was an error.
- LL_ERRS() << "image header chunk size was negative: "
- << data_size << LL_ENDL;
- return;
- }
-
- // this buffer gets saved off in the packet list
- U8 *data = new U8[data_size];
- msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
-
- LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- if (!image)
- {
- delete [] data;
- return;
- }
- if(log_texture_traffic)
- {
- gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ;
- }
-
- //image->getLastPacketTimer()->reset();
- bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data);
- if (!res)
- {
- delete[] data;
- }
-}
-
-// static
-void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data)
-{
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
-
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-
- // Receives image packet, copy into image object,
- // checks if all packets received, decompresses if so.
-
- LLUUID id;
- U16 packet_num;
-
- char ip_string[256];
- u32_to_ip_string(msg->getSenderIP(),ip_string);
-
- U32Bytes received_size ;
- if (msg->getReceiveCompressedSize())
- {
- received_size = (U32Bytes)msg->getReceiveCompressedSize() ;
- }
- else
- {
- received_size = (U32Bytes)msg->getReceiveSize() ;
- }
-
- add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, F64Bytes(received_size));
- add(LLStatViewer::TEXTURE_PACKETS, 1);
-
- //llprintline("Start decode, image header...");
- msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
- msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num);
- S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
-
- if (!data_size)
- {
- return;
- }
- if (data_size < 0)
- {
- // msg->getSizeFast() is probably trying to tell us there
- // was an error.
- LL_ERRS() << "image data chunk size was negative: "
- << data_size << LL_ENDL;
- return;
- }
- if (data_size > MTUBYTES)
- {
- LL_ERRS() << "image data chunk too large: " << data_size << " bytes" << LL_ENDL;
- return;
- }
- U8 *data = new U8[data_size];
- msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
-
- LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- if (!image)
- {
- delete [] data;
- return;
- }
- if(log_texture_traffic)
- {
- gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ;
- }
-
- //image->getLastPacketTimer()->reset();
- bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data);
- if (!res)
- {
- delete[] data;
- }
-}
-
-
// We've been that the asset server does not contain the requested image id.
// static
void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data)
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index bd60c990b5..454574f7d6 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -1,10 +1,10 @@
/**
- * @file llviewertexturelinumimagest.h
+ * @file llviewertexturelist.h
* @brief Object for managing the list of images within a region
*
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -92,11 +92,12 @@ class LLViewerTextureList
friend class LLLocalBitmap;
public:
- static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec);
- static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image);
+ static BOOL createUploadFile(const std::string& filename,
+ const std::string& out_filename,
+ const U8 codec,
+ const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, bool force_lossless = false);
static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
- static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
- static void receiveImagePacket(LLMessageSystem *msg, void **user_data);
public:
LLViewerTextureList();
@@ -126,7 +127,9 @@ public:
S32 getNumImages() { return mImageList.size(); }
+ // Local UI images
void doPreloadImages();
+ // Network images. Needs caps and cache to work
void doPrefetchImages();
void clearFetchingRequests();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 15f20d1d34..88058d1137 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -103,7 +103,6 @@
#include "llfilepicker.h"
#include "llfirstuse.h"
#include "llfloater.h"
-#include "llfloaterbuildoptions.h"
#include "llfloaterbuyland.h"
#include "llfloatercamera.h"
#include "llfloaterland.h"
@@ -228,6 +227,7 @@ extern BOOL gDebugClicks;
extern BOOL gDisplaySwapBuffers;
extern BOOL gDepthDirty;
extern BOOL gResizeScreenTexture;
+extern BOOL gCubeSnapshot;
LLViewerWindow *gViewerWindow = NULL;
@@ -597,29 +597,6 @@ public:
{
LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
- if (gGLManager.mHasATIMemInfo)
- {
- S32 meminfo[4];
- glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
-
- addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f));
- ypos += y_inc;
-
- if (gGLManager.mHasVertexBufferObject)
- {
- glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo);
- addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f));
- ypos += y_inc;
- }
- }
- else if (gGLManager.mHasNVXMemInfo)
- {
- S32 free_memory;
- glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
- addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f));
- ypos += y_inc;
- }
-
//show streaming cost/triangle count of known prims in current region OR selection
{
F32 cost = 0.f;
@@ -761,6 +738,12 @@ public:
ypos += y_inc;
addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f)));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f)));
ypos += y_inc;
}
@@ -1556,9 +1539,11 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
showCursor();
getWindow()->setMouseClipping(FALSE);
- // If losing focus while keys are down, reset them.
+ // If losing focus while keys are down, handle them as
+ // an 'up' to correctly release states, then reset states
if (gKeyboard)
{
+ gKeyboard->resetKeyDownAndHandle();
gKeyboard->resetKeys();
}
@@ -1900,7 +1885,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
gSavedSettings.getBOOL("RenderVSyncEnable"),
!gHeadlessClient,
p.ignore_pixel_depth,
- gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
+ 0); //don't use window level anti-aliasing
if (NULL == mWindow)
{
@@ -1979,14 +1964,9 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
// Initialize OpenGL Renderer
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
- !gGLManager.mHasVertexBufferObject)
- {
- gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
- }
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
- gGL.init() ;
+ gGL.init(true);
if (LLFeatureManager::getInstance()->isSafe()
|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
@@ -1997,11 +1977,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
}
- if (!gGLManager.mHasDepthClamp)
- {
- LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL;
- }
-
// If we crashed while initializng GL stuff last time, disable certain features
if (gSavedSettings.getBOOL("RenderInitError"))
{
@@ -2221,6 +2196,7 @@ void LLViewerWindow::initWorldUI()
gStatusBar->setShape(status_bar_container->getLocalRect());
// sync bg color with menu bar
gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
+ // add InBack so that gStatusBar won't be drawn over menu
status_bar_container->addChildInBack(gStatusBar);
status_bar_container->setVisible(TRUE);
@@ -2498,10 +2474,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)
//glViewport(0, 0, width, height );
- if (height > 0)
+ LLViewerCamera * camera = LLViewerCamera::getInstance(); // simpleton, might not exist
+ if (height > 0 && camera)
{
- LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
- LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ camera->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ camera->setAspect( getWorldViewAspectRatio() );
}
calcDisplayScale();
@@ -3200,6 +3177,11 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
void LLViewerWindow::handleScrollHWheel(S32 clicks)
{
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+
LLUI::getInstance()->resetMouseIdleTimer();
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
@@ -3358,7 +3340,7 @@ void LLViewerWindow::updateUI()
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
{
gDebugRaycastFaceHit = -1;
- gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE,
+ gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE,
&gDebugRaycastFaceHit,
&gDebugRaycastIntersection,
&gDebugRaycastTexCoord,
@@ -4182,13 +4164,16 @@ void LLViewerWindow::pickAsync( S32 x,
BOOL pick_rigged,
BOOL pick_unselectable)
{
- BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
- if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
- {
- // build mode allows interaction with all transparent objects
- // "Show Debug Alpha" means no object actually transparent
- pick_transparent = TRUE;
- }
+ // "Show Debug Alpha" means no object actually transparent
+ BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
+ if (LLDrawPoolAlpha::sShowDebugAlpha)
+ {
+ pick_transparent = TRUE;
+ }
+ else if (in_build_mode && !gSavedSettings.getBOOL("SelectInvisibleObjects"))
+ {
+ pick_transparent = FALSE;
+ }
LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, TRUE, pick_unselectable, callback);
schedulePick(pick_info);
@@ -4246,10 +4231,10 @@ void LLViewerWindow::returnEmptyPicks()
}
// Performs the GL object/land pick.
-LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle)
+LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle, BOOL pick_unselectable)
{
BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
- if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
+ if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
{
// build mode allows interaction with all transparent objects
// "Show Debug Alpha" means no object actually transparent
@@ -4295,6 +4280,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
S32 this_face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a *intersection,
LLVector2 *uv,
@@ -4365,7 +4351,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
{
if (this_object->isHUDAttachment()) // is a HUD object?
{
- if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged,
+ if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
face_hit, intersection, uv, normal, tangent))
{
found = this_object;
@@ -4373,7 +4359,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
}
else // is a world object
{
- if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged,
+ if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
face_hit, intersection, uv, normal, tangent))
{
found = this_object;
@@ -4387,7 +4373,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
if (!found) // if not found in HUD, look in world:
{
- found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged,
+ found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged, pick_unselectable,
face_hit, intersection, uv, normal, tangent);
if (found && !pick_transparent)
{
@@ -4645,8 +4631,8 @@ void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
else
pick_type = LLFilePicker::FFSAVE_ALL;
- (new LLFilePickerReplyThread(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
- boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb)))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
+ boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb));
}
else
{
@@ -4860,7 +4846,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
// PRE SNAPSHOT
gDisplaySwapBuffers = FALSE;
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
setCursor(UI_CURSOR_WAIT);
// Hide all the UI widgets first and draw a frame
@@ -4914,8 +4900,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;
if (scratch_space.allocate(image_width, image_height, color_fmt, true, true))
{
- original_width = gPipeline.mDeferredScreen.getWidth();
- original_height = gPipeline.mDeferredScreen.getHeight();
+ original_width = gPipeline.mRT->deferredScreen.getWidth();
+ original_height = gPipeline.mRT->deferredScreen.getHeight();
if (gPipeline.allocateScreenBuffer(image_width, image_height))
{
@@ -4994,8 +4980,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
- gObjectList.generatePickList(*LLViewerCamera::getInstance());
-
// Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen.
// In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y
for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)
@@ -5158,9 +5142,10 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
gDisplaySwapBuffers = FALSE;
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
setCursor(UI_CURSOR_WAIT);
BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
@@ -5172,13 +5157,13 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
LLPipeline::sShowHUDAttachments = FALSE;
LLRect window_rect = getWorldViewRectRaw();
- S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mDeferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw();
- S32 original_height = LLPipeline::sRenderDeferred ? gPipeline.mDeferredScreen.getHeight() : gViewerWindow->getWorldViewHeightRaw();
+ S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw();
+ S32 original_height = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getHeight() : gViewerWindow->getWorldViewHeightRaw();
LLRenderTarget scratch_space;
U32 color_fmt = GL_RGBA;
const bool use_depth_buffer = true;
- const bool use_stencil_buffer = true;
+ const bool use_stencil_buffer = false;
if (scratch_space.allocate(image_width, image_height, color_fmt, use_depth_buffer, use_stencil_buffer))
{
if (gPipeline.allocateScreenBuffer(image_width, image_height))
@@ -5254,6 +5239,149 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
return true;
}
+void display_cube_face();
+
+BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render)
+{
+ // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
+ LL_PROFILE_GPU_ZONE("cubeSnapshot");
+ llassert(LLPipeline::sRenderDeferred);
+ llassert(!gCubeSnapshot); //assert a snapshot isn't already in progress
+
+ U32 res = gPipeline.mRT->deferredScreen.getWidth();
+
+ //llassert(res <= gPipeline.mRT->deferredScreen.getWidth());
+ //llassert(res <= gPipeline.mRT->deferredScreen.getHeight());
+
+ // save current view/camera settings so we can restore them afterwards
+ S32 old_occlusion = LLPipeline::sUseOcclusion;
+
+ // set new parameters specific to the 360 requirements
+ LLPipeline::sUseOcclusion = 0;
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ LLViewerCamera saved_camera = LLViewerCamera::instance();
+ glh::matrix4f saved_proj = get_current_projection();
+ glh::matrix4f saved_mod = get_current_modelview();
+
+ // camera constants for the square, cube map capture image
+ camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV
+ camera->setView(F_PI_BY_TWO);
+ camera->yaw(0.0);
+ camera->setOrigin(origin);
+ camera->setNear(near_clip);
+
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
+
+ U32 dynamic_render_types[] = {
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
+ LLPipeline::RENDER_TYPE_PARTICLES
+ };
+ constexpr U32 dynamic_render_type_count = sizeof(dynamic_render_types) / sizeof(U32);
+ bool prev_dynamic_render_type[dynamic_render_type_count];
+
+
+ if (!dynamic_render)
+ {
+ for (int i = 0; i < dynamic_render_type_count; ++i)
+ {
+ prev_dynamic_render_type[i] = gPipeline.hasRenderType(dynamic_render_types[i]);
+ if (prev_dynamic_render_type[i])
+ {
+ gPipeline.toggleRenderType(dynamic_render_types[i]);
+ }
+ }
+ }
+
+ BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
+ if (prev_draw_ui != false)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+
+ LLPipeline::sShowHUDAttachments = FALSE;
+ LLRect window_rect = getWorldViewRectRaw();
+
+ mWorldViewRectRaw.set(0, res, res, 0);
+
+ // these are the 6 directions we will point the camera, see LLCubeMapArray::sTargets
+ LLVector3 look_dirs[6] = {
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+ LLVector3(0, 1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1)
+ };
+
+ LLVector3 look_upvecs[6] = {
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1),
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0)
+ };
+
+ // for each of six sides of cubemap
+ //for (int i = 0; i < 6; ++i)
+ int i = face;
+ {
+ // set up camera to look in each direction
+ camera->lookDir(look_dirs[i], look_upvecs[i]);
+
+ // turning this flag off here prohibits the screen swap
+ // to present the new page to the viewer - this stops
+ // the black flash in between captures when the number
+ // of render passes is more than 1. We need to also
+ // set it here because code in LLViewerDisplay resets
+ // it to TRUE each time.
+ gDisplaySwapBuffers = FALSE;
+
+ // actually render the scene
+ gCubeSnapshot = TRUE;
+ display_cube_face();
+ gCubeSnapshot = FALSE;
+ }
+
+ gDisplaySwapBuffers = TRUE;
+
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ if (prev_draw_ui != false)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+ }
+
+ if (!dynamic_render)
+ {
+ for (int i = 0; i < dynamic_render_type_count; ++i)
+ {
+ if (prev_dynamic_render_type[i])
+ {
+ gPipeline.toggleRenderType(dynamic_render_types[i]);
+ }
+ }
+ }
+
+ LLPipeline::sShowHUDAttachments = TRUE;
+
+ gPipeline.resetDrawOrders();
+ mWorldViewRectRaw = window_rect;
+
+ // restore original view/camera/avatar settings settings
+ *camera = saved_camera;
+ set_current_modelview(saved_mod);
+ set_current_projection(saved_proj);
+ LLPipeline::sUseOcclusion = old_occlusion;
+
+ // ====================================================
+ return true;
+}
+
void LLViewerWindow::destroyWindow()
{
if (mWindow)
@@ -5923,7 +6051,7 @@ void LLPickInfo::fetchResults()
}
LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
- NULL, -1, mPickTransparent, mPickRigged, &face_hit,
+ NULL, -1, mPickTransparent, mPickRigged, mPickUnselectable, &face_hit,
&intersection, &uv, &normal, &tangent, &start, &end);
mPickPt = mMousePt;
@@ -6068,7 +6196,7 @@ void LLPickInfo::getSurfaceInfo()
if (objectp)
{
if (gViewerWindow->cursorIntersect(ll_round((F32)mMousePt.mX), ll_round((F32)mMousePt.mY), 1024.f,
- objectp, -1, mPickTransparent, mPickRigged,
+ objectp, -1, mPickTransparent, mPickRigged, mPickUnselectable,
&mObjectFace,
&intersection,
&mSTCoords,
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 979a560508..387a2cb06f 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -68,6 +68,8 @@ class LLWindowListener;
class LLViewerWindowListener;
class LLVOPartGroup;
class LLPopupView;
+class LLCubeMap;
+class LLCubeMapArray;
#define PICK_HALF_WIDTH 5
#define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -360,6 +362,20 @@ public:
BOOL simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes);
+
+
+ // take a cubemap snapshot
+ // origin - vantage point to take the snapshot from
+ // cubearray - cubemap array for storing the results
+ // index - cube index in the array to use (cube index, not face-layer)
+ // face - which cube face to update
+ // near_clip - near clip setting to use
+ BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars);
+
+
+ // special implementation of simpleSnapshot for reflection maps
+ BOOL reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes);
+
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
BOOL isSnapshotLocSet() const;
void resetSnapshotLoc() const;
@@ -389,7 +405,7 @@ public:
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
BOOL pick_unselectable = FALSE);
- LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE);
+ LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE, BOOL pick_unselectable = TRUE);
LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
LLVector4a* intersection);
@@ -398,6 +414,7 @@ public:
S32 this_face = -1,
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL,
LLVector4a *intersection = NULL,
LLVector2 *uv = NULL,
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b8ebe92430..72c3e03104 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @File llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation of LLViewerObject
*
@@ -183,8 +183,6 @@ const F32 MAX_STANDOFF_DISTANCE_CHANGE = 32;
// Should probably be 4 or 3, but didn't want to change it while change other logic - SJB
const S32 SWITCH_TO_BAKED_DISCARD = 5;
-const F32 FOOT_COLLIDE_FUDGE = 0.04f;
-
const F32 HOVER_EFFECT_MAX_SPEED = 3.f;
const F32 HOVER_EFFECT_STRENGTH = 0.f;
const F32 UNDERWATER_EFFECT_STRENGTH = 0.1f;
@@ -585,7 +583,6 @@ private:
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
-S32 LLVOAvatar::sFreezeCounter = 0;
U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors
bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)
F32 LLVOAvatar::sRenderDistance = 256.f;
@@ -610,7 +607,6 @@ S32 LLVOAvatar::sNumVisibleChatBubbles = 0;
BOOL LLVOAvatar::sDebugInvisible = FALSE;
BOOL LLVOAvatar::sShowAttachmentPoints = FALSE;
BOOL LLVOAvatar::sShowAnimationDebug = FALSE;
-BOOL LLVOAvatar::sShowFootPlane = FALSE;
BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
F32 LLVOAvatar::sLODFactor = 1.f;
F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
@@ -779,6 +775,13 @@ std::string LLVOAvatar::avString() const
void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment)
{
+ if (gDisconnected)
+ {
+ // If we disconected, these values are likely to be invalid and
+ // avString() might crash due to a dead sAvatarDictionary
+ return;
+ }
+
LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
<< "sec ]"
<< avString()
@@ -1777,6 +1780,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -1883,6 +1887,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -1913,7 +1918,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
{
LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
@@ -2810,6 +2815,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (detailed_update)
{
U32 draw_order = 0;
+ S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment();
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -2849,7 +2855,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
}
// if selecting any attachments, update all of them as non-damped
- if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment())
+ if (attachment_selected)
{
gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
}
@@ -4105,8 +4111,7 @@ void LLVOAvatar::computeUpdatePeriod()
&& (!isSelf() || visually_muted)
&& !isUIAvatar()
&& (sLimitNonImpostors || visually_muted)
- && !mNeedsAnimUpdate
- && !sFreezeCounter)
+ && !mNeedsAnimUpdate)
{
const LLVector4a* ext = mDrawable->getSpatialExtents();
LLVector4a size;
@@ -4619,7 +4624,12 @@ bool LLVOAvatar::updateCharacter(LLAgent &agent)
}
else if (!getParent() && isSitting() && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED))
{
- getOffObject();
+ // If we are starting up, motion might be loading
+ LLMotion *motionp = mMotionController.findMotion(ANIM_AGENT_SIT_GROUND_CONSTRAINED);
+ if (!motionp || !mMotionController.isMotionLoading(motionp))
+ {
+ getOffObject();
+ }
}
//--------------------------------------------------------------------
@@ -5074,42 +5084,6 @@ U32 LLVOAvatar::renderSkinned()
return num_indices;
}
- // render collision normal
- // *NOTE: this is disabled (there is no UI for enabling sShowFootPlane) due
- // to DEV-14477. the code is left here to aid in tracking down the cause
- // of the crash in the future. -brad
- if (sShowFootPlane && mDrawable.notNull())
- {
- LLVector3 slaved_pos = mDrawable->getPositionAgent();
- LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]);
- F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW];
- LLVector3 collide_point = slaved_pos;
- collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE);
-
- gGL.begin(LLRender::LINES);
- {
- F32 SQUARE_SIZE = 0.2f;
- gGL.color4f(1.f, 0.f, 0.f, 1.f);
-
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]);
-
- }
- gGL.end();
- gGL.flush();
- }
//--------------------------------------------------------------------
// render all geometry attached to the skeleton
//--------------------------------------------------------------------
@@ -6174,7 +6148,21 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
if (iter == mJointMap.end() || iter->second == NULL)
{ //search for joint and cache found joint in lookup table
- jointp = mRoot->findJoint(name);
+ if (mJointAliasMap.empty())
+ {
+ getJointAliases();
+ }
+ joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
+ std::string canonical_name;
+ if (alias_iter != mJointAliasMap.end())
+ {
+ canonical_name = alias_iter->second;
+ }
+ else
+ {
+ canonical_name = name;
+ }
+ jointp = mRoot->findJoint(canonical_name);
mJointMap[name] = jointp;
}
else
@@ -7226,6 +7214,14 @@ LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx)
}
//-----------------------------------------------------------------------------
+// hideHair()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::hideHair()
+{
+ mMeshLOD[MESH_ID_HAIR]->setVisible(FALSE, TRUE);
+}
+
+//-----------------------------------------------------------------------------
// hideSkirt()
//-----------------------------------------------------------------------------
void LLVOAvatar::hideSkirt()
@@ -10230,23 +10226,6 @@ LLHost LLVOAvatar::getObjectHost() const
}
}
-//static
-void LLVOAvatar::updateFreezeCounter(S32 counter)
-{
- if(counter)
- {
- sFreezeCounter = counter;
- }
- else if(sFreezeCounter > 0)
- {
- sFreezeCounter--;
- }
- else
- {
- sFreezeCounter = 0;
- }
-}
-
BOOL LLVOAvatar::updateLOD()
{
if (mDrawable.isNull())
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 3c3decaad6..df3eebee2c 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -164,6 +164,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -174,6 +175,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -326,7 +328,6 @@ public:
static bool sLimitNonImpostors; // use impostors for far away avatars
static F32 sRenderDistance; // distance at which avatars will render.
static BOOL sShowAnimationDebug; // show animation debug info
- static BOOL sShowFootPlane; // show foot collision plane reported by server
static BOOL sShowCollisionVolumes; // show skeletal collision volumes
static BOOL sVisibleInFirstPerson;
static S32 sNumLODChangesThisFrame;
@@ -618,14 +619,6 @@ private:
BOOL mCulled;
//--------------------------------------------------------------------
- // Freeze counter
- //--------------------------------------------------------------------
-public:
- static void updateFreezeCounter(S32 counter = 0);
-private:
- static S32 sFreezeCounter;
-
- //--------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------
public:
@@ -808,6 +801,7 @@ public:
void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);
void processAvatarAppearance(LLMessageSystem* mesgsys);
void applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params);
+ void hideHair();
void hideSkirt();
void startAppearanceAnimation();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 4080a61fb0..d8b82d3114 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -67,6 +67,7 @@
#include "llsdserialize.h"
#include "llcallstack.h"
#include "llcorehttputil.h"
+#include "lluiusage.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -2661,6 +2662,7 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
{
if (isAgentAvatarValid())
{
+ LLUIUsage::instance().logCommand("Avatar.CustomizeStart");
if (!gAgentAvatarp->mEndCustomizeCallback.get())
{
gAgentAvatarp->mEndCustomizeCallback = new LLUpdateAppearanceOnDestroy;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index db8ad183f0..55fc663496 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -366,15 +366,6 @@ void LLVOCacheEntry::updateDebugSettings()
}
timer.reset();
- //the number of frames invisible objects stay in memory
- static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime");
- sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum
-
- //min radius: all objects within this radius remain loaded in memory
- static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
- sNearRadius = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance
- sNearRadius = llmax(sNearRadius, 1.f); //minimum value is 1.0m
-
//objects within the view frustum whose visible area is greater than this threshold will be loaded
static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold");
sFrontPixelThreshold = front_pixel_threshold;
@@ -384,29 +375,38 @@ void LLVOCacheEntry::updateDebugSettings()
sRearPixelThreshold = rear_pixel_threshold;
sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold.
- // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
- static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
- sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m
- sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius".
- sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance.
-
- //make the above parameters adaptive to memory usage
+ //make parameters adaptive to memory usage
//starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB
static LLCachedControl<U32> low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound");
static LLCachedControl<U32> high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound");
LLMemory::updateMemoryInfo() ;
U32 allocated_mem = LLMemory::getAllocatedMemKB().value();
- allocated_mem /= 1024; //convert to MB.
- if(allocated_mem < low_mem_bound_MB)
- {
- return;
- }
- F32 adjust_factor = llmax(0.f, (F32)(high_mem_bound_MB - allocated_mem) / (high_mem_bound_MB - low_mem_bound_MB));
-
- sRearFarRadius = llmin(adjust_factor * sRearFarRadius, 96.f); //[0.f, 96.f]
- sMinFrameRange = (U32)llclamp(adjust_factor * sMinFrameRange, 10.f, 64.f); //[10, 64]
- sNearRadius = llmax(adjust_factor * sNearRadius, 1.0f);
+ static const F32 KB_to_MB = 1.f / 1024.f;
+ U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB);
+ const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB;
+ const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1]
+
+ //min radius: all objects within this radius remain loaded in memory
+ static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
+ static const F32 MIN_RADIUS = 1.0f;
+ const F32 draw_radius = gAgentCamera.mDrawDistance;
+ const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance]
+ sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor);
+
+ // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
+ static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
+ const F32 min_radius_plus_one = sNearRadius + 1.f;
+ const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance;
+ const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance]
+ sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor);
+
+ //the number of frames invisible objects stay in memory
+ static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime");
+ static const U32 MIN_FRAMES = 10;
+ static const U32 MAX_FRAMES = 64;
+ const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64
+ sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor);
}
//static
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 9a41eedb54..36d66cccef 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -594,7 +594,7 @@ U32 LLVOGrass::getPartitionType() const
}
LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
mPartitionType = LLViewerRegion::PARTITION_GRASS;
@@ -602,7 +602,7 @@ LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
mDepthMask = TRUE;
mSlopRatio = 0.1f;
mRenderPass = LLRenderPass::PASS_GRASS;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
+ mBufferUsage = GL_DYNAMIC_DRAW;
}
void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
@@ -626,7 +626,7 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count
if (drawablep->isAnimating())
{
- group->mBufferUsage = GL_STREAM_DRAW_ARB;
+ group->mBufferUsage = GL_STREAM_DRAW;
}
U32 count = 0;
@@ -758,7 +758,7 @@ void LLVOGrass::updateDrawable(BOOL force_damped)
}
// virtual
-BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index 5634e048eb..63876dc099 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -79,6 +79,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 52a6395618..28bd5a3c97 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -93,7 +93,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
if (!face->getVertexBuffer())
{
face->setSize(5, 12);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW);
if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for VOGround to "
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index f971554c9d..b0eb8d962c 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -770,8 +770,6 @@ LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string
mReceivedCall(FALSE)
{
// make sure URI reflects encoded version of other user's agent id
- // *NOTE: in case of Avaline call generated SIP URL will be incorrect.
- // But it will be overridden in LLVoiceChannelP2P::setSessionHandle() called when agent accepts call
setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id));
}
@@ -911,8 +909,6 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s
else
{
LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL;
- // In the case of an incoming AvaLine call, the generated URI will be different from the
- // original one. This is because the P2P URI is based on avatar UUID but Avaline is not.
// See LLVoiceClient::sessionAddedEvent()
setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID));
}
@@ -947,22 +943,5 @@ void LLVoiceChannelP2P::setState(EState state)
void LLVoiceChannelP2P::addToTheRecentPeopleList()
{
- bool avaline_call = LLIMModel::getInstance()->findIMSession(mSessionID)->isAvalineSessionType();
-
- if (avaline_call)
- {
- LLSD call_data;
- std::string call_number = LLVoiceChannel::getSessionName();
-
- call_data["avaline_call"] = true;
- call_data["session_id"] = mSessionID;
- call_data["call_number"] = call_number;
- call_data["date"] = LLDate::now();
-
- LLRecentPeople::instance().add(mOtherUserID, call_data);
- }
- else
- {
- LLRecentPeople::instance().add(mOtherUserID);
- }
+ LLRecentPeople::instance().add(mOtherUserID);
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index e2bd1a39c7..2ef2d66f18 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -37,6 +37,7 @@
#include "llui.h"
#include "llkeyboard.h"
#include "llagent.h"
+#include "lluiusage.h"
const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f;
@@ -200,6 +201,7 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion()
LLVoiceVersionInfo result;
result.serverVersion = std::string();
result.serverType = std::string();
+ result.mBuildVersion = std::string();
return result;
}
}
@@ -602,6 +604,10 @@ void LLVoiceClient::setMuteMic(bool muted)
void LLVoiceClient::setUserPTTState(bool ptt)
{
+ if (ptt)
+ {
+ LLUIUsage::instance().logCommand("Agent.EnableMicrophone");
+ }
mUserPTTState = ptt;
updateMicMuteLogic();
mMicroChangedSignal();
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index cf527a4464..246883b611 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -95,6 +95,7 @@ struct LLVoiceVersionInfo
{
std::string serverType;
std::string serverVersion;
+ std::string mBuildVersion;
};
//////////////////////////////////
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 6e08a2ff12..34e561174c 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -356,7 +356,7 @@ void LLVoiceVisualizer::render()
//---------------------------------------------------------------
LLGLSPipelineAlpha alpha_blend;
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
//-------------------------------------------------------------
// create coordinates of the geometry for the dot
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 19036a3f77..ac6369e4e2 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -690,6 +690,10 @@ void LLVivoxVoiceClient::voiceControlCoro()
// surviving longer than LLVivoxVoiceClient
voiceControlStateMachine(state);
}
+ catch (const LLCoros::Stop&)
+ {
+ LL_DEBUGS("LLVivoxVoiceClient") << "Received a shutdown exception" << LL_ENDL;
+ }
catch (const LLContinueError&)
{
LOG_UNHANDLED_EXCEPTION("LLVivoxVoiceClient");
@@ -1606,13 +1610,33 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
}
else
{
- LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
-
+ LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
+ if (channel != NULL)
+ {
+ if (channel->getSessionName().empty() && channel->getSessionID().isNull())
+ {
+ if (LLViewerParcelMgr::getInstance()->allowAgentVoice())
+ {
+ LL_WARNS("Voice") << "No channel credentials for default channel" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
+ }
+ }
}
}
else
{
- LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
+ if (LLViewerParcelMgr::getInstance()->allowAgentVoice())
+ {
+ LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Voice") << "No voice credentials" << LL_ENDL;
+ }
}
// set the spatial channel. If no voice credentials or uri are
@@ -4572,6 +4596,23 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
}
}
+void LLVivoxVoiceClient::voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id)
+{
+ // We don't generally need to process this. However, one occurence is when we first connect, and so it is the
+ // earliest opportunity to learn what we're connected to.
+ if (statusCode)
+ {
+ LL_WARNS("Voice") << "VoiceServiceConnectionStateChangedEvent statusCode: " << statusCode <<
+ "statusString: " << statusString << LL_ENDL;
+ return;
+ }
+ if (build_id.empty())
+ {
+ return;
+ }
+ mVoiceVersion.mBuildVersion = build_id;
+}
+
void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)
{
LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL;
@@ -4758,7 +4799,7 @@ void LLVivoxVoiceClient::sessionState::VerifySessions()
if ((*it).expired())
{
LL_WARNS("Voice") << "Expired session found! removing" << LL_ENDL;
- mSession.erase(it++);
+ it = mSession.erase(it);
}
else
++it;
@@ -6815,7 +6856,7 @@ void LLVivoxVoiceClient::deleteVoiceFont(const LLUUID& id)
if (list_iter->second == id)
{
LL_DEBUGS("VoiceFont") << "Removing " << id << " from the voice font list." << LL_ENDL;
- mVoiceFontList.erase(list_iter++);
+ list_iter = mVoiceFontList.erase(list_iter);
mVoiceFontListDirty = true;
}
else
@@ -7554,6 +7595,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
connectorHandle = string;
else if (!stricmp("VersionID", tag))
versionID = string;
+ else if (!stricmp("Version", tag))
+ mBuildID = string;
else if (!stricmp("AccountHandle", tag))
accountHandle = string;
else if (!stricmp("State", tag))
@@ -7856,7 +7899,8 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
// We don't need to process this, but we also shouldn't warn on it, since that confuses people.
}
else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent"))
- { // Yet another ignored event
+ {
+ LLVivoxVoiceClient::getInstance()->voiceServiceConnectionStateChangedEvent(statusCode, statusString, mBuildID);
}
else if (!stricmp(eventTypeCstr, "AudioDeviceHotSwapEvent"))
{
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index cf30a4e86a..ebc3a62c35 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -465,6 +465,7 @@ protected:
void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType);
void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString);
void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
+ void voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id);
void auxAudioPropertiesEvent(F32 energy);
void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString);
void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string &notificationType);
@@ -969,6 +970,7 @@ protected:
std::string actionString;
std::string connectorHandle;
std::string versionID;
+ std::string mBuildID;
std::string accountHandle;
std::string sessionHandle;
std::string sessionGroupHandle;
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 068e8a131d..08f10a2028 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -65,7 +65,7 @@ void LLVOPartGroup::restoreGL()
{
//TODO: optimize out binormal mask here. Specular and normal coords as well.
- sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB);
+ sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW);
U32 count = LL_MAX_PARTICLE_COUNT;
if (!sVB->allocateBuffer(count*4, count*6, true))
{
@@ -485,6 +485,7 @@ BOOL LLVOPartGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -737,7 +738,7 @@ U32 LLVOPartGroup::getPartitionType() const
}
LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW, regionp)
{
mRenderPass = LLRenderPass::PASS_ALPHA;
mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;
@@ -756,6 +757,7 @@ LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) :
void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_GPU_ZONE("particle vbo");
if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
{
return;
@@ -845,9 +847,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
- U32 index_count = 0;
- U32 vertex_count = 0;
-
group->clearDrawMap();
LLVertexBuffer* buffer = group->mVertexBuffer;
@@ -913,9 +912,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
llassert(facep->getIndicesCount() == 6);
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
-
S32 idx = draw_vec.size()-1;
BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 4e4d6e609d..a45d381dfa 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -74,6 +74,7 @@ public:
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 01312d65cc..9f43fb9b82 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -531,7 +531,7 @@ void LLVOSky::initCubeMap()
images.push_back(mShinyTex[side].getImageRaw());
}
- if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+ if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps)
{
mCubeMap = new LLCubeMap(false);
}
@@ -576,7 +576,7 @@ void LLVOSky::restoreGL()
updateDirections(psky);
- if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+ if (gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps)
{
initCubeMap();
}
@@ -660,9 +660,7 @@ void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)
void LLVOSky::forceSkyUpdate()
{
mForceUpdate = TRUE;
-
- memset(&m_lastAtmosphericsVars, 0x00, sizeof(AtmosphericsVars));
-
+ m_lastAtmosphericsVars = {};
mCubeMapUpdateStage = -1;
}
@@ -1012,7 +1010,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
face->setSize(4, 6);
face->setGeomIndex(0);
face->setIndicesIndex(0);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW);
buff->allocateBuffer(4, 6, TRUE);
face->setVertexBuffer(buff);
@@ -1141,7 +1139,7 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const
if (!facep->getVertexBuffer())
{
facep->setSize(4, 6);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW);
if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to "
@@ -1381,7 +1379,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
if (!face->getVertexBuffer() || quads*4 != face->getGeomCount())
{
face->setSize(quads * 4, quads * 6);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW);
if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to "
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index b0af565867..69ae3cf23b 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -51,7 +51,7 @@ class LLVertexBufferTerrain : public LLVertexBuffer
{
public:
LLVertexBufferTerrain() :
- LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0 | MAP_TEXCOORD1 | MAP_COLOR, GL_DYNAMIC_DRAW_ARB)
+ LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0 | MAP_TEXCOORD1 | MAP_COLOR, GL_DYNAMIC_DRAW)
{
//texture coordinates 2 and 3 exist, but use the same data as texture coordinate 1
};
@@ -880,7 +880,7 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
}
}
-BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -1001,7 +1001,7 @@ U32 LLVOSurfacePatch::getPartitionType() const
}
LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW, regionp)
{
mOcclusionEnabled = FALSE;
mInfiniteFarClip = TRUE;
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index 884dbb3be3..aed67162d1 100644
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -85,6 +85,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 493162b47b..b6f8d162ba 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -921,7 +921,7 @@ void LLVOTree::updateMesh()
LLFace* facep = mDrawable->getFace(0);
if (!facep) return;
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW);
if (!buff->allocateBuffer(vert_count, index_count, TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on mesh update to "
@@ -1170,7 +1170,7 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mDrawable->setPositionGroup(pos);
}
-BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -1226,7 +1226,7 @@ U32 LLVOTree::getPartitionType() const
}
LLTreePartition::LLTreePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_TREE;
mPartitionType = LLViewerRegion::PARTITION_TREE;
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 93c22d2da3..996e970cf8 100644
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -111,6 +111,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f7678f5f26..663dd2d9ec 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -88,6 +88,7 @@
#include "llcallstack.h"
#include "llsculptidsize.h"
#include "llavatarappearancedefines.h"
+#include "llgltfmateriallist.h"
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f;
@@ -105,7 +106,7 @@ S32 LLVOVolume::mRenderComplexity_current = 0;
LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL;
LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;
-extern BOOL gGLDebugLoggingEnabled;
+extern BOOL gCubeSnapshot;
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
@@ -232,6 +233,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mMediaImplList.resize(getNumTEs());
mLastFetchedMediaVersion = -1;
+ mServerDrawableUpdateCount = 0;
memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
mMDCImplCount = 0;
mLastRiggingInfoLOD = -1;
@@ -327,6 +329,9 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
LLColor4U color;
const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
+ const bool previously_volume_changed = mVolumeChanged;
+ const bool previously_face_mapping_changed = mFaceMappingChanged;
+ const bool previously_color_changed = mColorChanged;
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
@@ -550,9 +555,31 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// ...and clean up any media impls
cleanUpMediaImpls();
+ if ((
+ (mVolumeChanged && !previously_volume_changed) ||
+ (mFaceMappingChanged && !previously_face_mapping_changed) ||
+ (mColorChanged && !previously_color_changed)
+ )
+ && !mLODChanged) {
+ onDrawableUpdateFromServer();
+ }
+
return retval;
}
+// Called when a volume, material, etc is updated by the server, possibly by a
+// script. If this occurs too often for this object, mark it as active so that
+// it doesn't disrupt the octree/render batches, thereby potentially causing a
+// big performance penalty.
+void LLVOVolume::onDrawableUpdateFromServer()
+{
+ constexpr U32 UPDATES_UNTIL_ACTIVE = 8;
+ ++mServerDrawableUpdateCount;
+ if (mDrawable && !mDrawable->isActive() && mServerDrawableUpdateCount > UPDATES_UNTIL_ACTIVE)
+ {
+ mDrawable->makeActive();
+ }
+}
void LLVOVolume::animateTextures()
{
@@ -717,7 +744,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
// Update the pixel area of all faces
- if (mDrawable.isNull())
+ if (mDrawable.isNull() || gCubeSnapshot)
{
return;
}
@@ -982,7 +1009,12 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
// Add it to the pipeline mLightSet
gPipeline.setLight(mDrawable, TRUE);
}
-
+
+ if (isReflectionProbe())
+ {
+ updateReflectionProbePtr();
+ }
+
updateRadius();
bool force_update = true; // avoid non-alpha mDistance update being optimized away
mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
@@ -1090,27 +1122,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
- bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject &&
- (!mVolumeImpl || !mVolumeImpl->isVolumeUnique());
-
- if (cache_in_vram)
- { //this volume might be used as source data for a transform object, put it in vram
- LLVolume* volume = getVolume();
- for (S32 i = 0; i < volume->getNumFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
- if (face.mVertexBuffer.notNull())
- { //already cached
- break;
- }
- volume->genTangents(i);
- LLFace::cacheFaceInVRAM(face);
- }
- }
-
- return TRUE;
+ return TRUE;
}
else if (NO_LOD == lod)
{
@@ -1670,7 +1682,7 @@ void LLVOVolume::regenFaces()
}
}
-BOOL LLVOVolume::genBBoxes(BOOL force_global)
+BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds)
{
LL_PROFILE_ZONE_SCOPED;
BOOL res = TRUE;
@@ -1689,7 +1701,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
// updates needed, set REBUILD_RIGGED accordingly.
// Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about.
- updateRiggedVolume();
+ updateRiggedVolume(false);
}
LLVolume* volume = mRiggedVolume;
@@ -1746,20 +1758,9 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
}
}
- bool rigged = false;
-
- if (!isAnimatedObject())
- {
- rigged = isRiggedMesh() && isAttachment();
- }
- else
- {
- rigged = isRiggedMesh() && getControlAvatar() && getControlAvatar()->mPlaying;
- }
-
if (any_valid_boxes)
{
- if (rebuild)
+ if (rebuild && should_update_octree_bounds)
{
//get the Avatar associated with this object if it's rigged
LLVOAvatar* avatar = nullptr;
@@ -1921,7 +1922,7 @@ void LLVOVolume::updateRelativeXform(bool force_identity)
}
}
-bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
+bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &should_update_octree_bounds)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
bool regen_faces = false;
@@ -1953,6 +1954,9 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
}
compiled = TRUE;
+ // new_lod > old_lod breaks a feedback loop between LOD updates and
+ // bounding box updates.
+ should_update_octree_bounds = should_update_octree_bounds || mSculptChanged || new_lod > old_lod;
sNumLODChanges += new_num_faces;
if ((S32)getNumTEs() != getVolume()->getNumFaces())
@@ -1991,7 +1995,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mDrawable->isState(LLDrawable::REBUILD_RIGGED))
{
- updateRiggedVolume();
+ updateRiggedVolume(false);
genBBoxes(FALSE);
mDrawable->clearState(LLDrawable::REBUILD_RIGGED);
}
@@ -2012,8 +2016,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
group->dirtyMesh();
}
- BOOL compiled = FALSE;
-
updateRelativeXform();
if (mDrawable.isNull()) // Not sure why this is happening, but it is...
@@ -2021,49 +2023,55 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
return TRUE; // No update to complete
}
+ BOOL compiled = FALSE;
+ // This should be true in most cases, unless we're sure no octree update is
+ // needed.
+ BOOL should_update_octree_bounds = bool(getRiggedVolume()) || mDrawable->isState(LLDrawable::REBUILD_POSITION) || !mDrawable->getSpatialExtents()->isFinite3();
+
if (mVolumeChanged || mFaceMappingChanged)
{
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
bool was_regen_faces = false;
+ should_update_octree_bounds = true;
if (mVolumeChanged)
{
- was_regen_faces = lodOrSculptChanged(drawable, compiled);
+ was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
drawable->setState(LLDrawable::REBUILD_VOLUME);
}
else if (mSculptChanged || mLODChanged || mColorChanged)
{
compiled = TRUE;
- was_regen_faces = lodOrSculptChanged(drawable, compiled);
+ was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
}
if (!was_regen_faces) {
regenFaces();
}
-
- genBBoxes(FALSE);
}
else if (mLODChanged || mSculptChanged || mColorChanged)
{
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
compiled = TRUE;
- lodOrSculptChanged(drawable, compiled);
+ lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED))
{
updateRiggedVolume(false);
}
- genBBoxes(FALSE);
}
// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
else
{
compiled = TRUE;
// All it did was move or we changed the texture coordinate offset
- genBBoxes(FALSE);
}
+ // Generate bounding boxes if needed, and update the object's size in the
+ // octree
+ genBBoxes(FALSE, should_update_octree_bounds);
+
// Update face flags
updateFaceFlags();
@@ -2154,7 +2162,8 @@ void LLVOVolume::setNumTEs(const U8 num_tes)
return ;
}
-//virtual
+
+//virtual
void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep)
{
BOOL changed = (mTEImages[index] != imagep);
@@ -2601,6 +2610,24 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa
return TEM_CHANGE_TEXTURE;
}
+S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat)
+{
+ S32 retval = LLViewerObject::setTEGLTFMaterialOverride(te, mat);
+
+ if (retval == TEM_CHANGE_TEXTURE)
+ {
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ }
+
+ return retval;
+}
+
+
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
{
S32 res = LLViewerObject::setTEScale(te, s, t);
@@ -2634,6 +2661,7 @@ S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t)
return res;
}
+
void LLVOVolume::updateTEData()
{
/*if (mDrawable.notNull())
@@ -3386,6 +3414,11 @@ F32 LLVOVolume::getSpotLightPriority() const
void LLVOVolume::updateSpotLightPriority()
{
+ if (gCubeSnapshot)
+ {
+ return;
+ }
+
F32 r = getLightRadius();
LLVector3 pos = mDrawable->getPositionAgent();
@@ -3488,6 +3521,129 @@ F32 LLVOVolume::getLightCutoff() const
}
}
+BOOL LLVOVolume::isReflectionProbe() const
+{
+ return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
+}
+
+void LLVOVolume::setIsReflectionProbe(BOOL is_probe)
+{
+ BOOL was_probe = isReflectionProbe();
+ if (is_probe != was_probe)
+ {
+ if (is_probe)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, TRUE, true);
+ }
+ else
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, FALSE, true);
+ }
+ }
+
+ updateReflectionProbePtr();
+}
+
+void LLVOVolume::setReflectionProbeAmbiance(F32 ambiance)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getAmbiance() != ambiance)
+ {
+ param_block->setAmbiance(ambiance);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+void LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getClipDistance() != near_clip)
+ {
+ param_block->setClipDistance(near_clip);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+void LLVOVolume::setReflectionProbeIsBox(bool is_box)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getIsBox() != is_box)
+ {
+ param_block->setIsBox(is_box);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+void LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getIsDynamic() != is_dynamic)
+ {
+ param_block->setIsDynamic(is_dynamic);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+F32 LLVOVolume::getReflectionProbeAmbiance() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getAmbiance();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+F32 LLVOVolume::getReflectionProbeNearClip() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getClipDistance();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+bool LLVOVolume::getReflectionProbeIsBox() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getIsBox();
+ }
+
+ return false;
+}
+
+bool LLVOVolume::getReflectionProbeIsDynamic() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getIsDynamic();
+ }
+
+ return false;
+}
+
U32 LLVOVolume::getVolumeInterfaceID() const
{
if (mVolumeImpl)
@@ -4076,7 +4232,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
}
}
- if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
+ if (face->isInAlphaPool())
{
alpha = 1;
}
@@ -4373,6 +4529,23 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u
gPipeline.setLight(mDrawable, is_light);
}
}
+
+ updateReflectionProbePtr();
+}
+
+void LLVOVolume::updateReflectionProbePtr()
+{
+ if (isReflectionProbe())
+ {
+ if (mReflectionProbe.isNull())
+ {
+ mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this);
+ }
+ }
+ else if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe = nullptr;
+ }
}
void LLVOVolume::setSelected(BOOL sel)
@@ -4423,7 +4596,7 @@ F32 LLVOVolume::getBinRadius()
{
LLFace* face = mDrawable->getFace(i);
if (!face) continue;
- if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
+ if (face->isInAlphaPool() &&
!face->canRenderAsMask())
{
alpha_wrap = TRUE;
@@ -4572,7 +4745,7 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
}
-BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -4583,6 +4756,14 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
return FALSE;
}
+ if (!pick_unselectable)
+ {
+ if (!LLSelectMgr::instance().canSelectObject(this))
+ {
+ return FALSE;
+ }
+ }
+
BOOL ret = FALSE;
LLVolume* volume = getVolume();
@@ -4593,7 +4774,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- updateRiggedVolume(true);
+ updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES);
volume = mRiggedVolume;
transform = false;
}
@@ -4668,6 +4849,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
continue;
}
+ // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree.
+ // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking.
+ updateRiggedVolume(true, i, false);
face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
&p, &tc, &n, &tn);
@@ -4791,13 +4975,13 @@ void LLVOVolume::clearRiggedVolume()
}
}
-void LLVOVolume::updateRiggedVolume(bool force_update)
+void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//Update mRiggedVolume to match current animation frame of avatar.
//Also update position/size in octree.
- if ((!force_update) && (!treatAsRigged()))
+ if ((!force_treat_as_rigged) && (!treatAsRigged()))
{
clearRiggedVolume();
@@ -4826,10 +5010,15 @@ void LLVOVolume::updateRiggedVolume(bool force_update)
updateRelativeXform();
}
- mRiggedVolume->update(skin, avatar, volume);
+ mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees);
}
-void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume)
+void LLRiggedVolume::update(
+ const LLMeshSkinInfo* skin,
+ LLVOAvatar* avatar,
+ const LLVolume* volume,
+ FaceIndex face_index,
+ bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
bool copy = false;
@@ -4860,7 +5049,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
if (is_paused)
{
S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame();
- if (frames_paused > 2)
+ if (frames_paused > 1)
{
return;
}
@@ -4879,7 +5068,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
S32 rigged_vert_count = 0;
S32 rigged_face_count = 0;
LLVector4a box_min, box_max;
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ S32 face_begin;
+ S32 face_end;
+ if (face_index == DO_NOT_UPDATE_FACES)
+ {
+ face_begin = 0;
+ face_end = 0;
+ }
+ else if (face_index == UPDATE_ALL_FACES)
+ {
+ face_begin = 0;
+ face_end = volume->getNumVolumeFaces();
+ }
+ else
+ {
+ face_begin = face_index;
+ face_end = face_begin + 1;
+ }
+ for (S32 i = face_begin; i < face_end; ++i)
{
const LLVolumeFace& vol_face = volume->getVolumeFace(i);
@@ -4964,15 +5170,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
+ if (rebuild_face_octrees)
{
- delete dst_face.mOctree;
- dst_face.mOctree = NULL;
-
- LLVector4a size;
- size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]);
- size.splat(size.getLength3().getF32()*0.5f);
-
- dst_face.createOctree(1.f);
+ dst_face.destroyOctree();
+ dst_face.createOctree();
}
}
}
@@ -5001,7 +5202,7 @@ U32 LLVOVolume::getPartitionType() const
}
LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp),
+: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW, regionp),
LLVolumeGeometryManager()
{
mLODPeriod = 32;
@@ -5009,7 +5210,7 @@ LLVolumeGeometryManager()
mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
mPartitionType = LLViewerRegion::PARTITION_VOLUME;
mSlopRatio = 0.25f;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
+ mBufferUsage = GL_DYNAMIC_DRAW;
}
LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
@@ -5021,7 +5222,7 @@ LLVolumeGeometryManager()
mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
+ mBufferUsage = GL_DYNAMIC_DRAW;
mSlopRatio = 0.25f;
}
@@ -5062,6 +5263,11 @@ bool can_batch_texture(LLFace* facep)
return false;
}
+ if (facep->getTextureEntry()->getGLTFRenderMaterial() != nullptr)
+ { // PBR materials break indexed texture batching
+ return false;
+ }
+
return true;
}
@@ -5153,6 +5359,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
return;
}
+ LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type));
+
U32 passType = type;
bool rigged = facep->isState(LLFace::RIGGED);
@@ -5217,8 +5425,23 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U8 index = facep->getTextureIndex();
- LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
- LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
+ LLMaterial* mat = nullptr;
+
+ LLUUID mat_id;
+
+ auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial();
+ if (gltf_mat != nullptr)
+ {
+ mat_id = gltf_mat->getHash(); // TODO: cache this hash
+ }
+ else
+ {
+ mat = facep->getTextureEntry()->getMaterialParams().get();
+ if (mat)
+ {
+ mat_id = facep->getTextureEntry()->getMaterialID().asUUID();
+ }
+ }
bool batchable = false;
@@ -5240,7 +5463,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
{
- if (mat || draw_vec[idx]->mMaterial)
+ if (mat || gltf_mat || draw_vec[idx]->mMaterial)
{ //can't batch textures when materials are present (yet)
batchable = false;
}
@@ -5272,7 +5495,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
#endif
- //draw_vec[idx]->mMaterial == mat &&
draw_vec[idx]->mMaterialID == mat_id &&
draw_vec[idx]->mFullbright == fullbright &&
draw_vec[idx]->mBump == bump &&
@@ -5329,11 +5551,16 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mEnvIntensity = spec;
draw_info->mSpecularMap = NULL;
draw_info->mMaterial = mat;
+ draw_info->mGLTFMaterial = gltf_mat;
draw_info->mShaderMask = shader_mask;
draw_info->mAvatar = facep->mAvatar;
draw_info->mSkinInfo = facep->mSkinInfo;
- if (mat)
+ if (gltf_mat)
+ {
+ // nothing to do, render pools will reference the GLTF material
+ }
+ else if (mat)
{
draw_info->mMaterialID = mat_id;
@@ -5495,6 +5722,8 @@ static inline void add_face(T*** list, U32* count, T* face)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+ llassert(!gCubeSnapshot);
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5579,7 +5808,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (drawablep->isAnimating())
{ //fall back to stream draw for animating verts
- useage = GL_STREAM_DRAW_ARB;
+ useage = GL_STREAM_DRAW;
}
LLVOVolume* vobj = drawablep->getVOVolume();
@@ -5589,6 +5818,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // apply any pending material overrides
+ gGLTFMaterialList.applyQueuedOverrides(vobj);
+
std::string vobj_name = llformat("Vol%p", vobj);
bool is_mesh = vobj->isMesh();
@@ -5652,7 +5884,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
avatar->addAttachmentOverridesForObject(vobj, NULL, false);
}
-
+
// Standard rigged mesh attachments:
bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
@@ -5672,6 +5904,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // HACK -- brute force this check every time a drawable gets rebuilt
+ vobj->updateTEMaterialTextures(i);
+#if 0
+#if LL_RELEASE_WITH_DEBUG_INFO
+ const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" );
+ const LLUUID obj_id( vobj->getID() );
+ bool is_pbr = (obj_id == pbr_id);
+#else
+ bool is_pbr = false;
+#endif
+#else
+ LLGLTFMaterial *gltf_mat = facep->getTextureEntry()->getGLTFRenderMaterial();
+ bool is_pbr = gltf_mat != nullptr;
+#endif
+
//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
// batch, it will recover its vertex buffer reference from the spatial group
facep->setVertexBuffer(NULL);
@@ -5696,7 +5943,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (facep->isState(LLFace::RIGGED))
{
//face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool();
if (pool)
{
pool->removeFace(facep);
@@ -5737,6 +5984,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+ if (is_pbr && gltf_mat && gltf_mat->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_BLEND)
+ {
+ type = LLDrawPool::POOL_PBR_OPAQUE;
+ }
+ else
if (type != LLDrawPool::POOL_ALPHA && force_simple)
{
type = LLDrawPool::POOL_SIMPLE;
@@ -5801,28 +6053,39 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (gPipeline.canUseWindLightShadersOnObjects()
&& LLPipeline::sRenderBump)
{
- if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() && !te->getMaterialID().isNull())
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
+
+ if (LLPipeline::sRenderDeferred &&
+ (gltf_mat != nullptr || (te->getMaterialParams().notNull() && !te->getMaterialID().isNull())))
{
- LLMaterial* mat = te->getMaterialParams().get();
- if (mat->getNormalID().notNull())
- {
- if (mat->getSpecularID().notNull())
- { //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
- add_face(sNormSpecFaces, normspec_count, facep);
- }
- else
- { //has normal map (needs texcoord1 and tangent)
- add_face(sNormFaces, norm_count, facep);
- }
- }
- else if (mat->getSpecularID().notNull())
- { //has specular map but no normal map, needs texcoord2
- add_face(sSpecFaces, spec_count, facep);
- }
- else
- { //has neither specular map nor normal map, only needs texcoord0
- add_face(sSimpleFaces, simple_count, facep);
- }
+ if (gltf_mat != nullptr)
+ {
+ // all gltf materials have all vertex attributes for now
+ add_face(sNormSpecFaces, normspec_count, facep);
+ }
+ else
+ {
+ LLMaterial* mat = te->getMaterialParams().get();
+ if (mat->getNormalID().notNull())
+ {
+ if (mat->getSpecularID().notNull())
+ { //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
+ add_face(sNormSpecFaces, normspec_count, facep);
+ }
+ else
+ { //has normal map (needs texcoord1 and tangent)
+ add_face(sNormFaces, norm_count, facep);
+ }
+ }
+ else if (mat->getSpecularID().notNull())
+ { //has specular map but no normal map, needs texcoord2
+ add_face(sSpecFaces, spec_count, facep);
+ }
+ else
+ { //has neither specular map nor normal map, only needs texcoord0
+ add_face(sSimpleFaces, simple_count, facep);
+ }
+ }
}
else if (te->getBumpmap())
{ //needs normal + tangent
@@ -5882,7 +6145,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
else
{
drawablep->clearState(LLDrawable::RIGGED);
- vobj->updateRiggedVolume();
+ vobj->updateRiggedVolume(false);
}
}
}
@@ -5992,7 +6255,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
+ if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL))
{
LLVOVolume* vobj = drawablep->getVOVolume();
@@ -6026,8 +6289,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- llassert(!face->isState(LLFace::RIGGED));
-
if (!face->getGeometryVolume(*volume, face->getTEOffset(),
vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
{ //something's gone wrong with the vertex buffer accounting, rebuild this group
@@ -6156,7 +6417,6 @@ struct CompareBatchBreakerRigged
}
};
-
U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
@@ -6164,16 +6424,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 geometryBytes = 0;
U32 buffer_usage = group->mBufferUsage;
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
- if (use_transform_feedback &&
- gTransformPositionProgram.mProgramObject && //transform shaders are loaded
- buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM
- !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights
- {
- buffer_usage = GL_DYNAMIC_COPY_ARB;
- }
-
#if LL_DARWIN
// HACK from Leslie:
// Disable VBO usage for alpha on Mac OS X because it kills the framerate
@@ -6239,11 +6489,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
buffer_index = -1;
}
- static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
- texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index);
-
- //NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
- texture_index_channels = llmin(texture_index_channels, 16);
+ texture_index_channels = LLGLSLShader::sIndexedTextureChannels;
bool flexi = false;
@@ -6405,9 +6651,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
- if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB)
+ if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW)
{
- buffer_usage = GL_STREAM_DRAW_ARB;
+ buffer_usage = GL_STREAM_DRAW;
}
//create vertex buffer
@@ -6509,15 +6755,24 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
- LLMaterial* mat = te->getMaterialParams().get();
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
- bool can_be_shiny = true;
- if (mat)
- {
- U8 mode = mat->getDiffuseAlphaMode();
- can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
- mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
- }
+ LLMaterial* mat = nullptr;
+ bool can_be_shiny = false;
+
+ // ignore traditional material if GLTF material is present
+ if (gltf_mat == nullptr)
+ {
+ mat = te->getMaterialParams().get();
+
+ can_be_shiny = true;
+ if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+ can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+ mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+ }
+ }
F32 te_alpha = te->getColor().mV[3];
bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
@@ -6526,10 +6781,18 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
is_alpha = (is_alpha || transparent) ? TRUE : FALSE;
- if (mat && LLPipeline::sRenderDeferred && !hud_group)
+ if ((gltf_mat || mat) && LLPipeline::sRenderDeferred && !hud_group)
{
bool material_pass = false;
+ if (gltf_mat)
+ { // all other parameters ignored if gltf material is present
+ if (gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ else
+ registerFace(group, facep, LLRenderPass::PASS_PBR_OPAQUE);
+ }
+ else
// 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
@@ -6811,7 +7074,7 @@ void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& verte
if (drawablep->isAnimating())
{ //fall back to stream draw for animating verts
- usage = GL_STREAM_DRAW_ARB;
+ usage = GL_STREAM_DRAW;
}
}
@@ -6840,7 +7103,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
if (drawablep->isAnimating())
{ //fall back to stream draw for animating verts
- usage = GL_STREAM_DRAW_ARB;
+ usage = GL_STREAM_DRAW;
}
//for each face
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 4cb7a5481c..003ab38d64 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -65,7 +65,15 @@ public:
{
}
- void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume);
+ using FaceIndex = S32;
+ static const FaceIndex UPDATE_ALL_FACES = -1;
+ static const FaceIndex DO_NOT_UPDATE_FACES = -2;
+ void update(
+ const LLMeshSkinInfo* skin,
+ LLVOAvatar* avatar,
+ const LLVolume* src_volume,
+ FaceIndex face_index = UPDATE_ALL_FACES,
+ bool rebuild_face_octrees = true);
std::string mExtraDebugText;
};
@@ -114,49 +122,50 @@ public:
};
public:
- LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- /*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references
+ LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
+ void markDead() override; // Override (and call through to parent) to clean up media references
- /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
+ LLDrawable* createDrawable(LLPipeline *pipeline) override;
void deleteFaces();
void animateTextures();
BOOL isVisible() const ;
- /*virtual*/ BOOL isActive() const;
- /*virtual*/ BOOL isAttachment() const;
- /*virtual*/ BOOL isRootEdit() const; // overridden for sake of attachments treating themselves as a root object
- /*virtual*/ BOOL isHUDAttachment() const;
+ BOOL isActive() const override;
+ BOOL isAttachment() const override;
+ BOOL isRootEdit() const override; // overridden for sake of attachments treating themselves as a root object
+ BOOL isHUDAttachment() const override;
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
- /*virtual*/ BOOL setParent(LLViewerObject* parent);
- S32 getLOD() const { return mLOD; }
+ /*virtual*/ BOOL setParent(LLViewerObject* parent) override;
+ S32 getLOD() const override { return mLOD; }
void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; }
bool isNoLOD() const { return NO_LOD == mLOD; }
- const LLVector3 getPivotPositionAgent() const;
+ const LLVector3 getPivotPositionAgent() const override;
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
- /*virtual*/ const LLMatrix4 getRenderMatrix() const;
+ /*virtual*/ const LLMatrix4 getRenderMatrix() const override;
typedef std::map<LLUUID, S32> texture_cost_t;
U32 getRenderCost(texture_cost_t &textures) const;
- /*virtual*/ F32 getEstTrianglesMax() const;
- /*virtual*/ F32 getEstTrianglesStreamingCost() const;
- /* virtual*/ F32 getStreamingCost() const;
- /*virtual*/ bool getCostData(LLMeshCostData& costs) const;
+ /*virtual*/ F32 getEstTrianglesMax() const override;
+ /*virtual*/ F32 getEstTrianglesStreamingCost() const override;
+ /* virtual*/ F32 getStreamingCost() const override;
+ /*virtual*/ bool getCostData(LLMeshCostData& costs) const override;
- /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const;
- /*virtual*/ U32 getHighLODTriangleCount();
+ /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override;
+ /*virtual*/ U32 getHighLODTriangleCount() override;
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
LLVector4a* normal = NULL, // return the surface normal at the intersection point
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
+ ) override;
LLVector3 agentPositionToVolume(const LLVector3& pos) const;
LLVector3 agentDirectionToVolume(const LLVector3& dir) const;
@@ -166,55 +175,59 @@ public:
BOOL getVolumeChanged() const { return mVolumeChanged; }
- /*virtual*/ F32 getRadius() const { return mVObjRadius; };
- const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
+ F32 getVObjRadius() const override { return mVObjRadius; };
+ const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const override;
- void markForUpdate(BOOL priority);
+ void markForUpdate(BOOL priority) override;
void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; }
- void faceMappingChanged() { mFaceMappingChanged=TRUE; };
+ void faceMappingChanged() override { mFaceMappingChanged=TRUE; }
- /*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
+ /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts
- /*virtual*/ void parameterChanged(U16 param_type, bool local_origin);
- /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
+ /*virtual*/ void parameterChanged(U16 param_type, bool local_origin) override;
+ /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) override;
+
+ // update mReflectionProbe based on isReflectionProbe()
+ void updateReflectionProbePtr();
/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num, const EObjectUpdateType update_type,
- LLDataPacker *dp);
-
- /*virtual*/ void setSelected(BOOL sel);
- /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp);
-
- /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped);
-
- /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) ;
- /*virtual*/ void setNumTEs(const U8 num_tes);
- /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep);
- /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
- /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump);
- /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny);
- /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright);
- /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
- /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
- /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
- /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
+ LLDataPacker *dp) override;
+
+ /*virtual*/ void setSelected(BOOL sel) override;
+ /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp) override;
+
+ /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped) override;
+
+ /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) override;
+ /*virtual*/ void setNumTEs(const U8 num_tes) override;
+ /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep) override;
+ /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid) override;
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color) override;
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color) override;
+ /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override;
+ /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override;
+ /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override;
+ /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override;
+ /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override;
+ /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override;
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) override;
static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
- /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
- /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
- /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
- /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
- /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen);
- /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media);
- /*virtual*/ BOOL setMaterial(const U8 material);
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override;
+ S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) override;
+ /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override;
+ /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override;
+ /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override;
+ /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen) override;
+ /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media) override;
+ /*virtual*/ BOOL setMaterial(const U8 material) override;
void setTexture(const S32 face);
S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
- /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
+ /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override;
void updateSculptTexture();
void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
void sculpt();
@@ -223,21 +236,21 @@ public:
void* user_data, S32 status, LLExtStat ext_status);
void updateRelativeXform(bool force_identity = false);
- /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
- /*virtual*/ void updateFaceSize(S32 idx);
- /*virtual*/ BOOL updateLOD();
- void updateRadius();
- /*virtual*/ void updateTextures();
+ /*virtual*/ BOOL updateGeometry(LLDrawable *drawable) override;
+ /*virtual*/ void updateFaceSize(S32 idx) override;
+ /*virtual*/ BOOL updateLOD() override;
+ void updateRadius() override;
+ /*virtual*/ void updateTextures() override;
void updateTextureVirtualSize(bool forced = false);
void updateFaceFlags();
void regenFaces();
- BOOL genBBoxes(BOOL force_global);
+ BOOL genBBoxes(BOOL force_global, BOOL should_update_octree_bounds = TRUE);
void preRebuild();
- virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
- virtual F32 getBinRadius();
+ virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max) override;
+ virtual F32 getBinRadius() override;
- virtual U32 getPartitionType() const;
+ virtual U32 getPartitionType() const override;
// For Lights
void setIsLight(BOOL is_light);
@@ -280,14 +293,27 @@ public:
F32 getLightRadius() const;
F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
F32 getLightCutoff() const;
-
+
+ // Reflection Probes
+ void setIsReflectionProbe(BOOL is_probe);
+ void setReflectionProbeAmbiance(F32 ambiance);
+ void setReflectionProbeNearClip(F32 near_clip);
+ void setReflectionProbeIsBox(bool is_box);
+ void setReflectionProbeIsDynamic(bool is_dynamic);
+
+ BOOL isReflectionProbe() const override;
+ F32 getReflectionProbeAmbiance() const;
+ F32 getReflectionProbeNearClip() const;
+ bool getReflectionProbeIsBox() const;
+ bool getReflectionProbeIsDynamic() const;
+
// Flexible Objects
U32 getVolumeInterfaceID() const;
- virtual BOOL isFlexible() const;
- virtual BOOL isSculpted() const;
- virtual BOOL isMesh() const;
- virtual BOOL isRiggedMesh() const;
- virtual BOOL hasLightTexture() const;
+ virtual BOOL isFlexible() const override;
+ virtual BOOL isSculpted() const override;
+ virtual BOOL isMesh() const override;
+ virtual BOOL isRiggedMesh() const override;
+ virtual BOOL hasLightTexture() const override;
BOOL isVolumeGlobal() const;
@@ -304,12 +330,12 @@ public:
void onSetExtendedMeshFlags(U32 flags);
void setExtendedMeshFlags(U32 flags);
bool canBeAnimatedObject() const;
- bool isAnimatedObject() const;
- virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent);
- virtual void afterReparent();
+ bool isAnimatedObject() const override;
+ virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent) override;
+ virtual void afterReparent() override;
//virtual
- void updateRiggingInfo();
+ void updateRiggingInfo() override;
S32 mLastRiggingInfoLOD;
// Functions that deal with media, or media navigation
@@ -362,8 +388,12 @@ public:
S32 getMDCImplCount() { return mMDCImplCount; }
- //rigged volume update (for raycasting)
- void updateRiggedVolume(bool force_update = false);
+ // Rigged volume update (for raycasting)
+ // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting
+ void updateRiggedVolume(
+ bool force_treat_as_rigged,
+ LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES,
+ bool rebuild_face_octrees = true);
LLRiggedVolume* getRiggedVolume();
//returns true if volume should be treated as a rigged volume
@@ -386,13 +416,14 @@ protected:
static S32 mRenderComplexity_last;
static S32 mRenderComplexity_current;
+ void onDrawableUpdateFromServer();
void requestMediaDataUpdate(bool isNew);
void cleanUpMediaImpls();
void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
void removeMediaImpl(S32 texture_index) ;
private:
- bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled);
+ bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &shouldUpdateOctreeBounds);
public:
@@ -424,6 +455,7 @@ private:
LLPointer<LLViewerFetchedTexture> mLightTexture;
media_list_t mMediaImplList;
S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1
+ U32 mServerDrawableUpdateCount;
S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
S32 mMDCImplCount;
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 089a7712c0..6f30092326 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -152,7 +152,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
LLVertexBuffer* buff = face->getVertexBuffer();
if (!buff || !buff->isWriteable())
{
- buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
+ buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on water update to "
@@ -295,7 +295,7 @@ U32 LLVOVoidWater::getPartitionType() const
}
LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW, regionp)
{
mInfiniteFarClip = TRUE;
mDrawableType = LLPipeline::RENDER_TYPE_WATER;
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index d1f584cbca..c7df343ad0 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -151,7 +151,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
if (mFsSkyVerts.isNull())
{
- mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+ mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW);
if (!mFsSkyVerts->allocateBuffer(4, 6, TRUE))
{
@@ -216,7 +216,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
for (U32 i = 0; i < strips_segments ;++i)
{
- LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+ LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW);
mStripsVerts[i] = segment;
U32 num_stacks_this_seg = stacks_per_seg;
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index ff899fe895..3cc82621c4 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -36,7 +36,7 @@
#include "llstring.h"
// newview
-#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
+#include "llavataractions.h" // for getProfileURL()
#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals
#include "llcorehttputil.h"
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 8abb49fba8..c5aff41746 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -763,14 +763,13 @@ void LLWorld::updateParticles()
void LLWorld::renderPropertyLines()
{
S32 region_count = 0;
- S32 vertex_count = 0;
for (region_list_t::iterator iter = mVisibleRegionList.begin();
iter != mVisibleRegionList.end(); ++iter)
{
LLViewerRegion* regionp = *iter;
region_count++;
- vertex_count += regionp->renderPropertyLines();
+ regionp->renderPropertyLines();
}
}
@@ -778,7 +777,6 @@ void LLWorld::renderPropertyLines()
void LLWorld::updateNetStats()
{
F64Bits bits;
- U32 packets = 0;
for (region_list_t::iterator iter = mActiveRegionList.begin();
iter != mActiveRegionList.end(); ++iter)
@@ -786,7 +784,6 @@ void LLWorld::updateNetStats()
LLViewerRegion* regionp = *iter;
regionp->updateNetStats();
bits += regionp->mBitsReceived;
- packets += llfloor( regionp->mPacketsReceived );
regionp->mBitsReceived = (F32Bits)0.f;
regionp->mPacketsReceived = 0.f;
}
@@ -820,7 +817,7 @@ void LLWorld::updateNetStats()
void LLWorld::printPacketsLost()
{
- LL_INFOS() << "Simulators:" << LL_ENDL;
+ LL_INFOS() << "Simulators:" << LL_ENDL;
LL_INFOS() << "----------" << LL_ENDL;
LLCircuitData *cdp = NULL;
@@ -855,6 +852,7 @@ F32 LLWorld::getLandFarClip() const
void LLWorld::setLandFarClip(const F32 far_clip)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT;
static S32 const rwidth = (S32)REGION_WIDTH_U32;
S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;
S32 const n2 = (llceil(far_clip) - 1) / rwidth;
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 59ac4554d7..6e994b4e68 100644..100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -58,9 +58,15 @@
#include "llglheaders.h"
+// # Constants
+static const F32 MAP_DEFAULT_SCALE = 128.f;
+static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f;
+static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f;
+static const F32 MAP_ZOOM_MAX_INTERP = 0.5f;
+static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f;
+
// Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py
// Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...)
-// # Constants
// OCEAN_COLOR = "#1D475F"
const F32 OCEAN_RED = (F32)(0x1D)/255.f;
const F32 OCEAN_GREEN = (F32)(0x47)/255.f;
@@ -92,14 +98,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL;
-F32 LLWorldMapView::sPanX = 0.f;
-F32 LLWorldMapView::sPanY = 0.f;
-F32 LLWorldMapView::sTargetPanX = 0.f;
-F32 LLWorldMapView::sTargetPanY = 0.f;
S32 LLWorldMapView::sTrackingArrowX = 0;
S32 LLWorldMapView::sTrackingArrowY = 0;
bool LLWorldMapView::sVisibleTilesLoaded = false;
-F32 LLWorldMapView::sMapScale = 128.f;
+F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE;
+LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f);
+LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer();
std::map<std::string,std::string> LLWorldMapView::sStringsMap;
@@ -166,20 +170,27 @@ void LLWorldMapView::cleanupClass()
sForSaleAdultImage = NULL;
}
-LLWorldMapView::LLWorldMapView()
-: LLPanel(),
- mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ),
- mItemPicked(FALSE),
- mPanning( FALSE ),
- mMouseDownPanX( 0 ),
- mMouseDownPanY( 0 ),
- mMouseDownX( 0 ),
- mMouseDownY( 0 ),
- mSelectIDStart(0)
+LLWorldMapView::LLWorldMapView() :
+ LLPanel(),
+ mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)),
+ mItemPicked(FALSE),
+ mPanX(0.f),
+ mPanY(0.f),
+ mTargetPanX(0.f),
+ mTargetPanY(0.f),
+ mPanning(FALSE),
+ mMouseDownPanX(0),
+ mMouseDownPanY(0),
+ mMouseDownX(0),
+ mMouseDownY(0),
+ mSelectIDStart(0),
+ mMapScale(0.f),
+ mTargetMapScale(0.f),
+ mMapIterpTime(MAP_ITERP_TIME_CONSTANT)
{
- //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
+ // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
- clearLastClick();
+ clearLastClick();
}
BOOL LLWorldMapView::postBuild()
@@ -210,6 +221,9 @@ BOOL LLWorldMapView::postBuild()
mTextBoxNorthEast ->reshapeToFitText();
mTextBoxSouthWest->reshapeToFitText();
mTextBoxNorthWest ->reshapeToFitText();
+
+ sZoomTimer.stop();
+ setScale(sMapScaleSetting, true);
return true;
}
@@ -227,59 +241,111 @@ void LLWorldMapView::cleanupTextures()
{
}
+void LLWorldMapView::zoom(F32 zoom)
+{
+ mTargetMapScale = scaleFromZoom(zoom);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomPivot = LLVector2(0, 0);
+ sZoomTimer.start();
+ }
+}
-// static
-void LLWorldMapView::setScale( F32 scale )
+void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y)
{
- if (scale != sMapScale)
- {
- F32 old_scale = sMapScale;
+ mTargetMapScale = scaleFromZoom(zoom);
+ sZoomPivot = LLVector2(x, y);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+}
- sMapScale = scale;
- if (sMapScale <= 0.f)
- {
- sMapScale = 0.1f;
- }
+F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); }
- F32 ratio = (scale / old_scale);
- sPanX *= ratio;
- sPanY *= ratio;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
- }
-}
+F32 LLWorldMapView::getScale() { return mMapScale; }
+// static
+void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; }
+
+// static
+F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; }
+
+void LLWorldMapView::setScale(F32 scale, bool snap)
+{
+ if (scale != mMapScale)
+ {
+ F32 old_scale = mMapScale;
+
+ mMapScale = scale;
+ // Set the scale used when saving the setting
+ sMapScaleSetting = scale;
+ if (mMapScale <= 0.f)
+ {
+ mMapScale = 0.1f;
+ }
+ mMapIterpTime = MAP_ITERP_TIME_CONSTANT;
+ F32 ratio = (scale / old_scale);
+ mPanX *= ratio;
+ mPanY *= ratio;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
+
+ // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here
+ if (!sZoomPivot.isExactlyZero())
+ {
+ LLVector2 relative_pivot;
+ relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0);
+ relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0);
+ LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale);
+ mPanX += zoom_pan_offset.mV[VX];
+ mPanY += zoom_pan_offset.mV[VY];
+ mTargetPanX += zoom_pan_offset.mV[VX];
+ mTargetPanY += zoom_pan_offset.mV[VY];
+ }
+ }
+
+ if (snap)
+ {
+ mTargetMapScale = scale;
+ }
+}
// static
-void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y )
+void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y)
{
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
}
// static
-void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap )
+void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap)
{
- sTargetPanX = (F32)x;
- sTargetPanY = (F32)y;
- if (snap)
- {
- sPanX = sTargetPanX;
- sPanY = sTargetPanY;
- }
- sVisibleTilesLoaded = false;
+ mMapIterpTime = MAP_ITERP_TIME_CONSTANT;
+ mTargetPanX = (F32) x;
+ mTargetPanY = (F32) y;
+ if (snap)
+ {
+ mPanX = mTargetPanX;
+ mPanY = mTargetPanY;
+ }
+ sVisibleTilesLoaded = false;
}
-bool LLWorldMapView::showRegionInfo()
+// static
+void LLWorldMapView::setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time)
{
- return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false);
+ setPan(x, y, snap);
+ mMapIterpTime = interp_time;
}
+bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); }
+
///////////////////////////////////////////////////////////////////////////////////
// HELPERS
@@ -300,9 +366,28 @@ void LLWorldMapView::draw()
mVisibleRegions.clear();
- // animate pan if necessary
- sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f));
- sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f));
+ // animate pan if necessary
+ mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(mMapIterpTime));
+ mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(mMapIterpTime));
+
+ //RN: snaps to zoom value because interpolation caused jitter in the text rendering
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+ bool snap_scale = false;
+ F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME);
+ F32 current_zoom_val = zoomFromScale(mMapScale);
+ F32 target_zoom_val = zoomFromScale(mTargetMapScale);
+ F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp);
+ if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD)
+ {
+ sZoomTimer.stop();
+ snap_scale = true;
+ new_zoom_val = target_zoom_val;
+ }
+ F32 map_scale = scaleFromZoom(new_zoom_val);
+ setScale(map_scale, snap_scale);
const S32 width = getRect().getWidth();
const S32 height = getRect().getHeight();
@@ -310,7 +395,7 @@ void LLWorldMapView::draw()
const F32 half_height = F32(height) / 2.0f;
LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
LLLocalClipRect clip(getLocalRect());
{
@@ -347,15 +432,15 @@ void LLWorldMapView::draw()
// Find x and y position relative to camera's center.
LLVector3d rel_region_pos = origin_global - camera_global;
- F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale;
- F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale;
+ F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale;
+ F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale;
// Coordinates of the sim in pixels in the UI panel
// When the view isn't panned, 0,0 = center of rectangle
- F32 bottom = sPanY + half_height + relative_y;
- F32 left = sPanX + half_width + relative_x;
- F32 top = bottom + sMapScale ;
- F32 right = left + sMapScale ;
+ F32 bottom = mPanY + half_height + relative_y;
+ F32 left = mPanX + half_width + relative_x;
+ F32 top = bottom + mMapScale ;
+ F32 right = left + mMapScale ;
// Discard if region is outside the screen rectangle (not visible on screen)
if ((top < 0.f) || (bottom > height) ||
@@ -416,7 +501,7 @@ void LLWorldMapView::draw()
if (overlayimage)
{
// Inform the fetch mechanism of the size we need
- S32 draw_size = ll_round(sMapScale);
+ S32 draw_size = ll_round(mMapScale);
overlayimage->setKnownDrawSize(ll_round(draw_size * LLUI::getScaleFactor().mV[VX]), ll_round(draw_size * LLUI::getScaleFactor().mV[VY]));
// Draw something whenever we have enough info
if (overlayimage->hasGLTexture())
@@ -444,7 +529,7 @@ void LLWorldMapView::draw()
}
// Draw the region name in the lower left corner
- if (sMapScale >= DRAW_TEXT_THRESHOLD)
+ if (mMapScale >= DRAW_TEXT_THRESHOLD)
{
LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD));
std::string mesg;
@@ -464,7 +549,7 @@ void LLWorldMapView::draw()
LLColor4::white,
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
S32_MAX, //max_chars
- sMapScale, //max_pixels
+ mMapScale, //max_pixels
NULL,
TRUE); //use ellipses
}
@@ -591,7 +676,7 @@ void LLWorldMapView::setVisible(BOOL visible)
void LLWorldMapView::drawMipmap(S32 width, S32 height)
{
// Compute the level of the mipmap to use for the current scale level
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// Set the tile boost level so that unused tiles get to 0
LLWorldMap::getInstance()->equalizeBoostLevels();
@@ -874,7 +959,7 @@ void LLWorldMapView::drawAgents()
void LLWorldMapView::drawFrustum()
{
// Draw frustum
- F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS;
+ F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS;
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
@@ -884,8 +969,8 @@ void LLWorldMapView::drawFrustum()
F32 half_width_pixels = half_width_meters * meters_to_pixels;
// Compute the frustum coordinates. Take the UI scale into account.
- F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]);
- F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]);
+ F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX) * LLUI::getScaleFactor().mV[VX]);
+ F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -942,13 +1027,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos )
LLVector3 pos_local;
pos_local.setVec(relative_pos_global); // convert to floats from doubles
- pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS;
- pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS;
// leave Z component in meters
- pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX;
- pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY;
+ pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX;
+ pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY;
return pos_local;
}
@@ -1019,12 +1104,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
// If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well
LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y )
{
- x -= llfloor((getRect().getWidth() / 2 + sPanX));
- y -= llfloor((getRect().getHeight() / 2 + sPanY));
+ x -= llfloor((getRect().getWidth() / 2 + mPanX));
+ y -= llfloor((getRect().getHeight() / 2 + mPanY));
LLVector3 pos_local( (F32)x, (F32)y, 0.f );
- pos_local *= ( REGION_WIDTH_METERS / sMapScale );
+ pos_local *= ( REGION_WIDTH_METERS / mMapScale );
LLVector3d pos_global;
pos_global.setVec( pos_local );
@@ -1481,7 +1566,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
LLWorldMap::getInstance()->cancelTracking();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// If the zoom level is not too far out already, test hits
if (level <= DRAW_SIMINFO_THRESHOLD)
{
@@ -1598,8 +1683,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask )
{
gFocusMgr.setMouseCapture( this );
- mMouseDownPanX = ll_round(sPanX);
- mMouseDownPanY = ll_round(sPanY);
+ mMouseDownPanX = ll_round(mPanX);
+ mMouseDownPanY = ll_round(mPanY);
mMouseDownX = x;
mMouseDownY = y;
sHandledLastClick = TRUE;
@@ -1614,8 +1699,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
{
// restore mouse cursor
S32 local_x, local_y;
- local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX);
- local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY);
+ local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX);
+ local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY);
LLRect clip_rect = getRect();
clip_rect.stretch(-8);
clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y);
@@ -1643,7 +1728,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
void LLWorldMapView::updateVisibleBlocks()
{
- if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD)
+ if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD)
{
// If we're zoomed out too much, we just don't load all those sim info: too much!
return;
@@ -1659,16 +1744,16 @@ void LLWorldMapView::updateVisibleBlocks()
const F32 half_height = F32(height) / 2.0f;
// Compute center into sim grid coordinates
- S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
- S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
+ S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
+ S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
// Compute the boundaries into sim grid coordinates
- S32 world_left = world_center_x - S32(half_width / sMapScale) - 1;
- S32 world_right = world_center_x + S32(half_width / sMapScale) + 1;
- S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1;
- S32 world_top = world_center_y + S32(half_height / sMapScale) + 1;
+ S32 world_left = world_center_x - S32(half_width / mMapScale) - 1;
+ S32 world_right = world_center_x + S32(half_width / mMapScale) + 1;
+ S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1;
+ S32 world_top = world_center_y + S32(half_height / mMapScale) + 1;
- //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
+ //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top);
}
@@ -1689,10 +1774,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask )
F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY());
// Set pan to value at start of drag + offset
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
gViewerWindow->moveCursorToCenter();
}
@@ -1789,4 +1874,8 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
return FALSE;
}
+// static
+F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; }
+// static
+F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); }
diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h
index a2a6dc53fb..ce8af76a82 100644
--- a/indra/newview/llworldmapview.h
+++ b/indra/newview/llworldmapview.h
@@ -67,12 +67,22 @@ public:
bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track);
void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id);
- // Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered)
- static void setScale( F32 scale );
- static void translatePan( S32 delta_x, S32 delta_y );
- static void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered)
+ // Zoom is used for UI and will interpolate the map scale over multiple frames.
+ void zoom(F32 zoom);
+ void zoomWithPivot(F32 zoom, S32 x, S32 y);
+ F32 getZoom();
+ // Scale is a linear scaling factor of in-world coordinates
+ F32 getScale();
+ // setScaleSetting/getScaleSetting are for the default map setting on login
+ static void setScaleSetting(F32 scaleSetting);
+ static F32 getScaleSetting();
+ // Pan is in pixels relative to the center of the map.
+ void translatePan( S32 delta_x, S32 delta_y );
+ void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ void setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time);
// Return true if the current scale level is above the threshold for accessing region info
- static bool showRegionInfo();
+ bool showRegionInfo();
LLVector3 globalPosToView(const LLVector3d& global_pos);
LLVector3d viewPosToGlobal(S32 x,S32 y);
@@ -153,14 +163,12 @@ public:
static LLUIImagePtr sForSaleImage;
static LLUIImagePtr sForSaleAdultImage;
- static F32 sMapScale; // scale = size of a region in pixels
-
BOOL mItemPicked;
- static F32 sPanX; // in pixels
- static F32 sPanY; // in pixels
- static F32 sTargetPanX; // in pixels
- static F32 sTargetPanY; // in pixels
+ F32 mPanX; // in pixels
+ F32 mPanY; // in pixels
+ F32 mTargetPanX; // in pixels
+ F32 mTargetPanY; // in pixels
static S32 sTrackingArrowX;
static S32 sTrackingArrowY;
static bool sVisibleTilesLoaded;
@@ -194,6 +202,19 @@ public:
private:
void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right);
+
+ void setScale(F32 scale, bool snap = true);
+
+ static F32 scaleFromZoom(F32 zoom);
+ static F32 zoomFromScale(F32 scale);
+
+ F32 mMapScale;
+ F32 mTargetMapScale;
+ static F32 sMapScaleSetting;
+ static LLVector2 sZoomPivot;
+ static LLFrameTimer sZoomTimer;
+
+ F32 mMapIterpTime;
};
#endif
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 2b400c5586..80e94c37f2 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -40,6 +40,7 @@
#include "httpoptions.h"
#include "httpheaders.h"
#include "bufferarray.h"
+#include "llversioninfo.h"
#include "llviewercontrol.h"
// Have to include these last to avoid queue redefinition!
@@ -378,6 +379,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+ std::string user_agent = llformat("%s %d.%d.%d (%d)",
+ LLVersionInfo::instance().getChannel().c_str(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
+ LLVersionInfo::instance().getBuild());
+
+ httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+
///* Setting the DNS cache timeout to -1 disables it completely.
//This might help with bug #503 */
//httpOpts->setDNSCacheTimeout(-1);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9ec3418132..b60b64ed1f 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -132,12 +132,12 @@
// NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
// NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
// const S32 WATER_REFLECT_NONE_WATER_OPAQUE = -2;
- const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1;
- const S32 WATER_REFLECT_MINIMAL = 0;
+ //const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1;
+ //const S32 WATER_REFLECT_MINIMAL = 0;
// const S32 WATER_REFLECT_TERRAIN = 1;
- const S32 WATER_REFLECT_STATIC_OBJECTS = 2;
- const S32 WATER_REFLECT_AVATARS = 3;
- const S32 WATER_REFLECT_EVERYTHING = 4;
+ //const S32 WATER_REFLECT_STATIC_OBJECTS = 2;
+ //const S32 WATER_REFLECT_AVATARS = 3;
+ //const S32 WATER_REFLECT_EVERYTHING = 4;
bool gShiftFrame = false;
@@ -203,7 +203,6 @@ F32 LLPipeline::RenderEdgeNormCutoff;
LLVector3 LLPipeline::RenderShadowGaussian;
F32 LLPipeline::RenderShadowBlurDistFactor;
bool LLPipeline::RenderDeferredAtmospheric;
-S32 LLPipeline::RenderReflectionDetail;
F32 LLPipeline::RenderHighlightFadeTime;
LLVector3 LLPipeline::RenderShadowClipPlanes;
LLVector3 LLPipeline::RenderShadowOrthoClipPlanes;
@@ -227,6 +226,7 @@ extern S32 gBoxFrame;
//extern BOOL gHideSelectedObjects;
extern BOOL gDisplaySwapBuffers;
extern BOOL gDebugGL;
+extern BOOL gCubeSnapshot;
bool gAvatarBacklight = false;
@@ -280,29 +280,6 @@ static LLStaticHashedString sKern("kern");
static LLStaticHashedString sKernScale("kern_scale");
//----------------------------------------
-std::string gPoolNames[] =
-{
- // Correspond to LLDrawpool enum render type
- "NONE",
- "POOL_SIMPLE",
- "POOL_GROUND",
- "POOL_FULLBRIGHT",
- "POOL_BUMP",
- "POOL_MATERIALS",
- "POOL_TERRAIN,"
- "POOL_SKY",
- "POOL_WL_SKY",
- "POOL_TREE",
- "POOL_ALPHA_MASK",
- "POOL_FULLBRIGHT_ALPHA_MASK",
- "POOL_GRASS",
- "POOL_INVISIBLE",
- "POOL_AVATAR",
- "POOL_VOIDWATER",
- "POOL_WATER",
- "POOL_GLOW",
- "POOL_ALPHA"
-};
void drawBox(const LLVector4a& c, const LLVector4a& r);
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
@@ -338,7 +315,6 @@ bool LLPipeline::sNoAlpha = false;
bool LLPipeline::sUseTriStrips = true;
bool LLPipeline::sUseFarClip = true;
bool LLPipeline::sShadowRender = false;
-bool LLPipeline::sWaterReflections = false;
bool LLPipeline::sRenderGlow = false;
bool LLPipeline::sReflectionRender = false;
bool LLPipeline::sDistortionRender = false;
@@ -350,6 +326,8 @@ bool LLPipeline::sRenderFrameTest = false;
bool LLPipeline::sRenderAttachedLights = true;
bool LLPipeline::sRenderAttachedParticles = true;
bool LLPipeline::sRenderDeferred = false;
+bool LLPipeline::sReflectionProbesEnabled = false;
+bool LLPipeline::sRenderPBR = false;
S32 LLPipeline::sVisibleLightCount = 0;
bool LLPipeline::sRenderingHUDs;
F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f;
@@ -363,11 +341,13 @@ void validate_framebuffer_object();
// Add color attachments for deferred rendering
// target -- RenderTarget to add attachments to
-// for_impostor -- whether or not these render targets are for an impostor (if true, avoids implicit sRGB conversions)
bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
{
- return target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) && //specular
- target.addColorAttachment(GL_RGB10_A2); //normal+z
+ bool valid = true
+ && target.addColorAttachment(GL_RGBA) // frag-data[1] specular OR PBR ORM
+ && target.addColorAttachment(GL_RGB10_A2) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight
+ && target.addColorAttachment(GL_RGBA); // frag_data[3] PBR emissive
+ return valid;
}
LLPipeline::LLPipeline() :
@@ -388,26 +368,9 @@ LLPipeline::LLPipeline() :
mGroupQ2Locked(false),
mResetVertexBuffers(false),
mLastRebuildPool(NULL),
- mAlphaPool(NULL),
- mSkyPool(NULL),
- mTerrainPool(NULL),
- mWaterPool(NULL),
- mGroundPool(NULL),
- mSimplePool(NULL),
- mGrassPool(NULL),
- mAlphaMaskPool(NULL),
- mFullbrightAlphaMaskPool(NULL),
- mFullbrightPool(NULL),
- mInvisiblePool(NULL),
- mGlowPool(NULL),
- mBumpPool(NULL),
- mMaterialsPool(NULL),
- mWLSkyPool(NULL),
mLightMask(0),
mLightMovingMask(0),
- mLightingDetail(0),
- mScreenWidth(0),
- mScreenHeight(0)
+ mLightingDetail(0)
{
mNoiseMap = 0;
mTrueNoiseMap = 0;
@@ -436,10 +399,12 @@ void LLPipeline::init()
{
refreshCachedSettings();
+ mRT = &mMainRT;
+
gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump");
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
@@ -452,7 +417,8 @@ void LLPipeline::init()
stop_glerror();
//create render pass pools
- getPool(LLDrawPool::POOL_ALPHA);
+ getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);
+ getPool(LLDrawPool::POOL_ALPHA_POST_WATER);
getPool(LLDrawPool::POOL_SIMPLE);
getPool(LLDrawPool::POOL_ALPHA_MASK);
getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
@@ -462,6 +428,7 @@ void LLPipeline::init()
getPool(LLDrawPool::POOL_BUMP);
getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
+ getPool(LLDrawPool::POOL_PBR_OPAQUE);
resetFrameStats();
@@ -521,7 +488,7 @@ void LLPipeline::init()
if (mCubeVB.isNull())
{
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
@@ -537,8 +504,8 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors");
connectRefreshCachedSettingsSafe("RenderDelayVBUpdate");
connectRefreshCachedSettingsSafe("UseOcclusion");
- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
- connectRefreshCachedSettingsSafe("RenderDeferred");
+ // DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
+ // DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred");
connectRefreshCachedSettingsSafe("RenderDeferredSunWash");
connectRefreshCachedSettingsSafe("RenderFSAASamples");
connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
@@ -597,7 +564,6 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderShadowGaussian");
connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor");
connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric");
- connectRefreshCachedSettingsSafe("RenderReflectionDetail");
connectRefreshCachedSettingsSafe("RenderHighlightFadeTime");
connectRefreshCachedSettingsSafe("RenderShadowClipPlanes");
connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes");
@@ -657,8 +623,10 @@ void LLPipeline::cleanup()
LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL;
}
- delete mAlphaPool;
- mAlphaPool = NULL;
+ delete mAlphaPoolPreWater;
+ mAlphaPoolPreWater = nullptr;
+ delete mAlphaPoolPostWater;
+ mAlphaPoolPostWater = nullptr;
delete mSkyPool;
mSkyPool = NULL;
delete mTerrainPool;
@@ -715,7 +683,7 @@ void LLPipeline::destroyGL()
if (mMeshDirtyQueryObject)
{
- glDeleteQueriesARB(1, &mMeshDirtyQueryObject);
+ glDeleteQueries(1, &mMeshDirtyQueryObject);
mMeshDirtyQueryObject = 0;
}
}
@@ -732,8 +700,9 @@ void LLPipeline::requestResizeShadowTexture()
void LLPipeline::resizeShadowTexture()
{
- releaseShadowTargets();
- allocateShadowBuffer(mScreenWidth, mScreenHeight);
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
+ allocateShadowBuffer(mRT->width, mRT->height);
gResizeShadowTexture = FALSE;
}
@@ -744,10 +713,11 @@ void LLPipeline::resizeScreenTexture()
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
- if (gResizeScreenTexture || (resX != mScreen.getWidth()) || (resY != mScreen.getHeight()))
+ if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight()))
{
releaseScreenBuffers();
- releaseShadowTargets();
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
allocateScreenBuffer(resX,resY);
gResizeScreenTexture = FALSE;
}
@@ -767,42 +737,16 @@ void LLPipeline::allocatePhysicsBuffer()
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
- refreshCachedSettings();
-
- bool save_settings = sRenderDeferred;
- if (save_settings)
- {
- // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
- gSavedSettings.setBOOL("RenderInitError", TRUE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- }
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
- if (save_settings)
- {
- // don't disable shaders on next session
- gSavedSettings.setBOOL("RenderInitError", FALSE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- }
-
- if (ret == FBO_FAILURE)
- { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
- //NOTE: if the session closes successfully after this call, deferred rendering will be
- // disabled on future sessions
- if (LLPipeline::sRenderDeferred)
- {
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- LLPipeline::refreshCachedSettings();
- }
- }
-
return ret == FBO_SUCCESS_FULLRES;
}
LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
// try to allocate screen buffers at requested resolution and samples
// - on failure, shrink number of samples and try again
// - if not multisampled, shrink resolution and try again (favor X resolution over Y)
@@ -856,11 +800,20 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
- refreshCachedSettings();
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (mRT == &mMainRT)
+ { // hacky -- allocate auxillary buffer
+ gCubeSnapshot = TRUE;
+ mRT = &mAuxillaryRT;
+ U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2;
+ allocateScreenBuffer(res, res, samples);
+ mRT = &mMainRT;
+ gCubeSnapshot = FALSE;
+ }
// remember these dimensions
- mScreenWidth = resX;
- mScreenHeight = resY;
+ mRT->width = resX;
+ mRT->height = resY;
U32 res_mod = RenderResolutionDivisor;
@@ -872,7 +825,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (RenderUIBuffer)
{
- if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE))
+ if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE))
{
return false;
}
@@ -886,39 +839,33 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
const U32 occlusion_divisor = 3;
//allocate deferred rendering color buffers
- if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!addDeferredAttachments(mDeferredScreen)) return false;
+ if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ //if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!addDeferredAttachments(mRT->deferredScreen)) return false;
GLuint screenFormat = GL_RGBA16;
- if (gGLManager.mIsAMD)
- {
- screenFormat = GL_RGBA12;
- }
-
- if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA)
- {
- screenFormat = GL_RGBA16F_ARB;
- }
- if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+
+ mRT->deferredScreen.shareDepthBuffer(mRT->screen);
+
if (samples > 0)
{
- if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
}
else
{
- mFXAABuffer.release();
+ mRT->fxaaBuffer.release();
}
if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
- { //only need mDeferredLight for shadows OR ssao OR dof OR fxaa
- if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
+ { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
+ if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
else
{
- mDeferredLight.release();
+ mRT->deferredLight.release();
}
allocateShadowBuffer(resX, resY);
@@ -931,24 +878,20 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
else
{
- mDeferredLight.release();
+ mRT->deferredLight.release();
- releaseShadowTargets();
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
- mFXAABuffer.release();
- mScreen.release();
- mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
- mDeferredDepth.release();
- mOcclusionDepth.release();
+ mRT->fxaaBuffer.release();
+ mRT->screen.release();
+ mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first
+ //mRT->deferredDepth.release();
+ mRT->occlusionDepth.release();
- if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
+ if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
- if (LLPipeline::sRenderDeferred)
- { //share depth buffer between deferred targets
- mDeferredScreen.shareDepthBuffer(mScreen);
- }
-
gGL.getTexUnit(0)->disable();
stop_glerror();
@@ -961,68 +904,67 @@ inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0
bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
{
- refreshCachedSettings();
-
- if (LLPipeline::sRenderDeferred)
- {
- S32 shadow_detail = RenderShadowDetail;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (LLPipeline::sRenderDeferred)
+ {
+ S32 shadow_detail = RenderShadowDetail;
- const U32 occlusion_divisor = 3;
+ const U32 occlusion_divisor = 3;
- F32 scale = llmax(0.f,RenderShadowResolutionScale);
- U32 sun_shadow_map_width = BlurHappySize(resX, scale);
- U32 sun_shadow_map_height = BlurHappySize(resY, scale);
+ F32 scale = llmax(0.f, RenderShadowResolutionScale);
+ U32 sun_shadow_map_width = BlurHappySize(resX, scale);
+ U32 sun_shadow_map_height = BlurHappySize(resY, scale);
- if (shadow_detail > 0)
- { //allocate 4 sun shadow maps
- for (U32 i = 0; i < 4; i++)
- {
- if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ if (shadow_detail > 0)
+ { //allocate 4 sun shadow maps
+ for (U32 i = 0; i < 4; i++)
+ {
+ if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
{
return false;
}
- if (!mShadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width / occlusion_divisor, sun_shadow_map_height / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
{
return false;
}
- }
- }
- else
- {
- for (U32 i = 0; i < 4; i++)
- {
- releaseShadowTarget(i);
- }
- }
-
- U32 width = (U32) (resX*scale);
- U32 height = width;
+ }
+ }
+ else
+ {
+ for (U32 i = 0; i < 4; i++)
+ {
+ releaseSunShadowTarget(i);
+ }
+ }
- if (shadow_detail > 1)
- { //allocate two spot shadow maps
- U32 spot_shadow_map_width = width;
- U32 spot_shadow_map_height = height;
- for (U32 i = 4; i < 6; i++)
- {
- if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
- {
- return false;
- }
- if (!mShadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE))
- {
- return false;
- }
- }
+ if (!gCubeSnapshot) // hack to not allocate spot shadow maps during ReflectionMapManager init
+ {
+ U32 width = (U32)(resX * scale);
+ U32 height = width;
+
+ if (shadow_detail > 1)
+ { //allocate two spot shadow maps
+ U32 spot_shadow_map_width = width;
+ U32 spot_shadow_map_height = height;
+ for (U32 i = 0; i < 2; i++)
+ {
+ if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
+ {
+ return false;
+ }
+ if (!mSpotShadowOcclusion[i].allocate(spot_shadow_map_width / occlusion_divisor, height / occlusion_divisor, 0, TRUE, FALSE))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ releaseSpotShadowTargets();
+ }
}
- else
- {
- for (U32 i = 4; i < 6; i++)
- {
- releaseShadowTarget(i);
- }
- }
- }
+ }
return true;
}
@@ -1036,23 +978,21 @@ void LLPipeline::updateRenderTransparentWater()
//static
void LLPipeline::updateRenderBump()
{
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump");
}
// static
void LLPipeline::updateRenderDeferred()
{
- sRenderDeferred = !gUseWireframe &&
- RenderDeferred &&
- LLRenderTarget::sUseFBO &&
- LLPipeline::sRenderBump &&
- WindLightUseAtmosShaders &&
- (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
+ sRenderPBR = sRenderDeferred;
+ static LLCachedControl<S32> sProbeDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
+ sReflectionProbesEnabled = sProbeDetail >= 0 && gGLManager.mGLVersion > 3.99f;
}
// static
void LLPipeline::refreshCachedSettings()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
@@ -1063,11 +1003,10 @@ void LLPipeline::refreshCachedSettings()
LLPipeline::sUseOcclusion =
(!gUseWireframe
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
- && gSavedSettings.getBOOL("UseOcclusion")
- && gGLManager.mHasOcclusionQuery) ? 2 : 0;
+ && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0;
- WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+ WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+ RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred");
RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
@@ -1126,7 +1065,6 @@ void LLPipeline::refreshCachedSettings()
RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian");
RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric");
- RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail");
RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime");
RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes");
RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
@@ -1190,40 +1128,56 @@ void LLPipeline::releaseLUTBuffers()
LLImageGL::deleteTextures(1, &mLightFunc);
mLightFunc = 0;
}
+
+ mPbrBrdfLut.release();
}
void LLPipeline::releaseShadowBuffers()
{
- releaseShadowTargets();
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
}
void LLPipeline::releaseScreenBuffers()
{
- mUIScreen.release();
- mScreen.release();
- mFXAABuffer.release();
+ mRT->uiScreen.release();
+ mRT->screen.release();
+ mRT->fxaaBuffer.release();
mPhysicsDisplay.release();
- mDeferredScreen.release();
- mDeferredDepth.release();
- mDeferredLight.release();
- mOcclusionDepth.release();
+ mRT->deferredScreen.release();
+ mRT->deferredDepth.release();
+ mRT->deferredLight.release();
+ mRT->occlusionDepth.release();
}
-void LLPipeline::releaseShadowTarget(U32 index)
+void LLPipeline::releaseSunShadowTarget(U32 index)
{
- mShadow[index].release();
- mShadowOcclusion[index].release();
+ llassert(index < 4);
+ mRT->shadow[index].release();
+ mRT->shadowOcclusion[index].release();
}
-void LLPipeline::releaseShadowTargets()
+void LLPipeline::releaseSunShadowTargets()
{
- for (U32 i = 0; i < 6; i++)
+ for (U32 i = 0; i < 4; i++)
{
- releaseShadowTarget(i);
+ releaseSunShadowTarget(i);
}
}
+void LLPipeline::releaseSpotShadowTargets()
+{
+ if (!gCubeSnapshot) // hack to avoid freeing spot shadows during ReflectionMapManager init
+ {
+ for (U32 i = 0; i < 2; i++)
+ {
+ mSpotShadow[i].release();
+ mSpotShadowOcclusion[i].release();
+ }
+ }
+}
+
void LLPipeline::createGLBuffers()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
@@ -1231,10 +1185,9 @@ void LLPipeline::createGLBuffers()
assertInitialized();
updateRenderDeferred();
- if (LLPipeline::sWaterReflections)
+ if (LLPipeline::sRenderTransparentWater)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
- mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE);
}
@@ -1256,8 +1209,8 @@ void LLPipeline::createGLBuffers()
}
allocateScreenBuffer(resX, resY);
- mScreenWidth = 0;
- mScreenHeight = 0;
+ mRT->width = 0;
+ mRT->height = 0;
if (sRenderDeferred)
{
@@ -1277,7 +1230,7 @@ void LLPipeline::createGLBuffers()
LLImageGL::generateTextures(1, &mNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -1292,7 +1245,7 @@ void LLPipeline::createGLBuffers()
LLImageGL::generateTextures(1, &mTrueNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -1357,6 +1310,21 @@ void LLPipeline::createLUTBuffers()
delete [] ls;
}
+
+ mPbrBrdfLut.allocate(512, 512, GL_RG16F, false, false);
+ mPbrBrdfLut.bindTarget();
+ gDeferredGenBrdfLutProgram.bind();
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 1);
+ gGL.vertex2f(1, -1);
+ gGL.vertex2f(1, 1);
+ gGL.end();
+ gGL.flush();
+
+ gDeferredGenBrdfLutProgram.unbind();
+ mPbrBrdfLut.flush();
}
}
@@ -1573,9 +1541,12 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_MATERIALS:
poolp = mMaterialsPool;
break;
- case LLDrawPool::POOL_ALPHA:
- poolp = mAlphaPool;
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ poolp = mAlphaPoolPreWater;
break;
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ poolp = mAlphaPoolPostWater;
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -1597,6 +1568,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mWLSkyPool;
break;
+ case LLDrawPool::POOL_PBR_OPAQUE:
+ poolp = mPBROpaquePool;
+ break;
+
default:
llassert(0);
LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL;
@@ -1638,6 +1613,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
}
LLMaterial* mat = te->getMaterialParams().get();
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
bool color_alpha = te->getColor().mV[3] < 0.999f;
bool alpha = color_alpha;
@@ -1663,7 +1639,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
}
}
- if (alpha)
+ if (alpha || (gltf_mat && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND))
{
return LLDrawPool::POOL_ALPHA;
}
@@ -1671,6 +1647,10 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
{
return LLDrawPool::POOL_BUMP;
}
+ else if (gltf_mat)
+ {
+ return LLDrawPool::POOL_PBR_OPAQUE;
+ }
else if (mat && !alpha)
{
return LLDrawPool::POOL_MATERIALS;
@@ -2028,6 +2008,7 @@ void LLPipeline::updateMove()
//static
F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera)
{
+ llassert(!gCubeSnapshot); // shouldn't be doing ANY of this during cube snap shots
LLVector3 lookAt = center - camera.getOrigin();
F32 dist = lookAt.length();
@@ -2329,8 +2310,7 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep)
{
static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion");
- static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
- && gGLManager.mHasOcclusionQuery;
+ static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion");
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
@@ -2353,11 +2333,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
{
if (LLPipeline::sRenderDeferred && can_use_occlusion)
{
- mOcclusionDepth.bindTarget();
+ mRT->occlusionDepth.bindTarget();
}
else
{
- mScreen.bindTarget();
+ mRT->screen.bindTarget();
}
}
@@ -2392,7 +2372,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
{
if (mCubeVB.isNull())
{ //cube VB will be used for issuing occlusion queries
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
}
@@ -2438,17 +2418,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
stop_glerror();
}
- if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) &&
- !gPipeline.canUseWindLightShaders() &&
- gSky.mVOGroundp.notNull() &&
- gSky.mVOGroundp->mDrawable.notNull() &&
- !LLPipeline::sWaterReflections)
- {
- gSky.mVOGroundp->mDrawable->setVisible(camera);
- sCull->pushDrawable(gSky.mVOGroundp->mDrawable);
- }
-
-
if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) &&
gPipeline.canUseWindLightShaders() &&
gSky.mVOWLSkyp.notNull() &&
@@ -2479,11 +2448,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
{
if (LLPipeline::sRenderDeferred && can_use_occlusion)
{
- mOcclusionDepth.flush();
+ mRT->occlusionDepth.flush();
}
else
{
- mScreen.flush();
+ mRT->screen.flush();
}
}
}
@@ -2497,7 +2466,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
group->setVisible();
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
group->updateDistance(camera);
}
@@ -2513,6 +2482,13 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
sCull->pushVisibleGroup(group);
}
+ if (group->needsUpdate() ||
+ group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
+ {
+ // include this group in occlusion groups, not because it is an occluder, but because we want to run
+ // an occlusion query to find out if it's an occluder
+ markOccluder(group);
+ }
mNumVisibleNodes++;
}
@@ -2548,6 +2524,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
if (scratch_space)
{
GLint bits = 0;
+ llassert(!source.hasStencil()); // stencil buffer usage is deprecated
bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0;
bits |= GL_DEPTH_BUFFER_BIT;
scratch_space->copyContents(source,
@@ -2603,15 +2580,25 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(!gCubeSnapshot);
+#if 0
downsampleDepthBuffer(source, dest, scratch_space);
dest.bindTarget();
doOcclusion(camera);
dest.flush();
+#else
+ // none of the above shenanigans should matter (enough) because we've preserved hierarchical Z before issuing occlusion queries
+ //source.bindTarget();
+ doOcclusion(camera);
+ //source.flush();
+#endif
}
void LLPipeline::doOcclusion(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("doOcclusion");
if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
{
@@ -2648,7 +2635,7 @@ void LLPipeline::doOcclusion(LLCamera& camera)
if (mCubeVB.isNull())
{ //cube VB will be used for issuing occlusion queries
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
@@ -2845,7 +2832,7 @@ void LLPipeline::rebuildPriorityGroups()
void LLPipeline::rebuildGroups()
{
- if (mGroupQ2.empty())
+ if (mGroupQ2.empty() || gCubeSnapshot)
{
return;
}
@@ -2895,6 +2882,10 @@ void LLPipeline::updateGeom(F32 max_dtime)
LLPointer<LLDrawable> drawablep;
LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE);
+ if (gCubeSnapshot)
+ {
+ return;
+ }
assertInitialized();
@@ -3134,6 +3125,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
}
}
+ mReflectionMapManager.shift(offseta);
+
LLHUDText::shiftAll(offset);
LLHUDNameTag::shiftAll(offset);
@@ -3314,7 +3307,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
}
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
LLSpatialGroup* last_group = NULL;
BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();
@@ -3396,7 +3389,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
stateSort(drawablep, camera);
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{ //avoid redundant stateSort calls
group->mLastUpdateDistance = group->mDistance;
}
@@ -3465,7 +3458,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
}
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
//if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here
{
@@ -3726,14 +3719,26 @@ void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize)
void LLPipeline::touchTextures(LLDrawInfo* info)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- for (int i = 0; i < info->mTextureList.size(); ++i)
+
+ auto& mat = info->mGLTFMaterial;
+ if (mat.notNull())
{
- touchTexture(info->mTextureList[i], info->mTextureListVSize[i]);
+ touchTexture(mat->mBaseColorTexture, info->mVSize);
+ touchTexture(mat->mNormalTexture, info->mVSize);
+ touchTexture(mat->mMetallicRoughnessTexture, info->mVSize);
+ touchTexture(mat->mEmissiveTexture, info->mVSize);
}
+ else
+ {
+ for (int i = 0; i < info->mTextureList.size(); ++i)
+ {
+ touchTexture(info->mTextureList[i], info->mTextureListVSize[i]);
+ }
- touchTexture(info->mTexture, info->mVSize);
- touchTexture(info->mSpecularMap, info->mVSize);
- touchTexture(info->mNormalMap, info->mVSize);
+ touchTexture(info->mTexture, info->mVSize);
+ touchTexture(info->mSpecularMap, info->mVSize);
+ touchTexture(info->mNormalMap, info->mVSize);
+ }
}
void LLPipeline::postSort(LLCamera& camera)
@@ -3743,21 +3748,26 @@ void LLPipeline::postSort(LLCamera& camera)
assertInitialized();
LL_PUSH_CALLSTACKS();
- //rebuild drawable geometry
- for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
- {
- LLSpatialGroup* group = *i;
- if (!sUseOcclusion ||
- !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
- {
- group->rebuildGeom();
- }
- }
- LL_PUSH_CALLSTACKS();
- //rebuild groups
- sCull->assertDrawMapsEmpty();
- rebuildPriorityGroups();
+ if (!gCubeSnapshot)
+ {
+ //rebuild drawable geometry
+ for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
+ {
+ LLSpatialGroup* group = *i;
+ if (!sUseOcclusion ||
+ !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ group->rebuildGeom();
+ }
+ }
+ LL_PUSH_CALLSTACKS();
+ //rebuild groups
+ sCull->assertDrawMapsEmpty();
+
+ rebuildPriorityGroups();
+ }
+
LL_PUSH_CALLSTACKS();
@@ -3773,7 +3783,7 @@ void LLPipeline::postSort(LLCamera& camera)
continue;
}
- if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY))
+ if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY) && !gCubeSnapshot)
{ //no way this group is going to be drawable without a rebuild
group->rebuildGeom();
}
@@ -3813,7 +3823,7 @@ void LLPipeline::postSort(LLCamera& camera)
LLDrawInfo* info = *k;
sCull->pushDrawInfo(j->first, info);
- if (!sShadowRender && !sReflectionRender)
+ if (!sShadowRender && !sReflectionRender && !gCubeSnapshot)
{
touchTextures(info);
addTrianglesDrawn(info->mCount, info->mDrawMode);
@@ -3828,7 +3838,7 @@ void LLPipeline::postSort(LLCamera& camera)
if (alpha != group->mDrawMap.end())
{ //store alpha groups for sorting
LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
if (bridge)
{
@@ -3877,11 +3887,11 @@ void LLPipeline::postSort(LLCamera& camera)
if (!mMeshDirtyQueryObject)
{
- glGenQueriesARB(1, &mMeshDirtyQueryObject);
+ glGenQueries(1, &mMeshDirtyQueryObject);
}
- glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
+ glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
}*/
//pack vertex buffers for groups that chose to delay their updates
@@ -3892,7 +3902,7 @@ void LLPipeline::postSort(LLCamera& camera)
/*if (use_transform_feedback)
{
- glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
}*/
mMeshDirtyGroup.clear();
@@ -3961,7 +3971,7 @@ void LLPipeline::postSort(LLCamera& camera)
}
LL_PUSH_CALLSTACKS();
// If managing your telehub, draw beacons at telehub and currently selected spawnpoint.
- if (LLFloaterTelehub::renderBeacons())
+ if (LLFloaterTelehub::renderBeacons() && !sShadowRender)
{
LLFloaterTelehub::addBeacons();
}
@@ -4007,13 +4017,12 @@ void render_hud_elements()
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
gPipeline.disableLights();
- LLGLDisable fog(GL_FOG);
LLGLSUIDefault gls_ui;
- LLGLEnable stencil(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
- glStencilMask(0xFFFFFFFF);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
+ //glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
+ //glStencilMask(0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
gGL.color4f(1,1,1,1);
@@ -4022,7 +4031,7 @@ void render_hud_elements()
if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
- LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d()
// Draw the tracking overlays
@@ -4035,9 +4044,6 @@ void render_hud_elements()
}
LLViewerParcelMgr::getInstance()->render();
LLViewerParcelMgr::getInstance()->renderParcelCollision();
-
- // Render name tags.
- LLHUDObject::renderAll();
}
else if (gForceRenderLandFence)
{
@@ -4050,7 +4056,6 @@ void render_hud_elements()
}
gUIProgram.unbind();
- gGL.flush();
}
void LLPipeline::renderHighlights()
@@ -4070,14 +4075,15 @@ void LLPipeline::renderHighlights()
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
LLGLDisable test(GL_ALPHA_TEST);
- LLGLEnable stencil(GL_STENCIL_TEST);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
gGL.flush();
- glStencilMask(0xFFFFFFFF);
- glClearStencil(1);
- glClear(GL_STENCIL_BUFFER_BIT);
+ // stencil ops are deprecated
+ //glStencilMask(0xFFFFFFFF);
+ //glClearStencil(1);
+ //glClear(GL_STENCIL_BUFFER_BIT);
- glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ //glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
+ //glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
gGL.setColorMask(false, false);
@@ -4089,8 +4095,8 @@ void LLPipeline::renderHighlights()
}
gGL.setColorMask(true, false);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // deprecated
+ //glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
//gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
@@ -4283,8 +4289,9 @@ U32 LLPipeline::sCurRenderPoolType = 0 ;
void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
-
+ LL_PROFILE_GPU_ZONE("renderGeom");
assertInitialized();
F32 saved_modelview[16];
@@ -4330,7 +4337,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
gGL.matrixMode(LLRender::MM_MODELVIEW);
LLGLSPipeline gls_pipeline;
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2);
@@ -4369,6 +4376,8 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
}
{
+ bool occlude = sUseOcclusion > 1;
+#if 1 // DEPRECATED -- requires forward rendering
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pools"); //LL_RECORD_BLOCK_TIME(FTM_POOLS);
// HACK: don't calculate local lights if we're rendering the HUD!
@@ -4380,7 +4389,6 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
setupHWLights(NULL);
}
- bool occlude = sUseOcclusion > 1;
U32 cur_type = 0;
pool_set_t::iterator iter1 = mPools.begin();
@@ -4402,6 +4410,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
doOcclusion(camera);
}
+
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0)
{
@@ -4449,17 +4458,18 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
}
iter1 = iter2;
stop_glerror();
+
}
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd");
LLVertexBuffer::unbind();
-
+#endif
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
if (occlude)
- {
+ { // catch uncommon condition where pools at drawpool grass and later are disabled
occlude = false;
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4529,19 +4539,23 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
LLGLState::checkStates();
// LLGLState::checkTextureChannels();
// LLGLState::checkClientArrays();
+#endif
}
-void LLPipeline::renderGeomDeferred(LLCamera& camera)
+void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
{
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
-
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
+ LL_PROFILE_GPU_ZONE("renderGeomDeferred");
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
+
+ bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
+
{
- // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function.
- // Solutions are:
- // 1. Use a new scope
- // 2. Use named zones
- // 3. Use transient zones
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);
LLGLEnable cull(GL_CULL_FACE);
@@ -4555,13 +4569,19 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
}
}
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
LLVertexBuffer::unbind();
LLGLState::checkStates();
LLGLState::checkTextureChannels();
+ if (LLViewerShaderMgr::instance()->mShaderLevel[LLViewerShaderMgr::SHADER_DEFERRED] > 1)
+ {
+ //update reflection probe uniform
+ mReflectionMapManager.updateUniforms();
+ }
+
U32 cur_type = 0;
gGL.setColorMask(true, true);
@@ -4574,6 +4594,17 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
cur_type = poolp->getType();
+ if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
+ {
+ llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots
+ occlude = false;
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ LLGLSLShader::bindNoShader();
+ doOcclusion(camera);
+ gGL.setColorMask(true, false);
+ }
+
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
{
@@ -4628,16 +4659,28 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
} // Tracy ZoneScoped
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS);
+ LL_PROFILE_GPU_ZONE("renderGeomPostDeferred");
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
+
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
calcNearbyLights(camera);
setupHWLights(NULL);
@@ -4645,7 +4688,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
gGL.setColorMask(true, false);
pool_set_t::iterator iter1 = mPools.begin();
- bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
while ( iter1 != mPools.end() )
{
@@ -4653,16 +4695,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
cur_type = poolp->getType();
- if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
- {
- occlude = false;
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
- LLGLSLShader::bindNoShader();
- doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
- gGL.setColorMask(true, false);
- }
-
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
{
@@ -4714,20 +4746,25 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(gGLModelView);
- if (occlude)
- {
- occlude = false;
- LLGLSLShader::bindNoShader();
- doOcclusion(camera);
- gGLLastMatrix = NULL;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(gGLModelView);
- }
+ if (!gCubeSnapshot)
+ {
+ // debug displays
+ renderHighlights();
+ mHighlightFaces.clear();
+
+ renderDebug();
+ }
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
void LLPipeline::renderGeomShadow(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("renderGeomShadow");
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -4927,7 +4964,7 @@ void LLPipeline::renderDebug()
const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear");
gGL.setColorMask(true, true);
glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // no stencil -- deprecated | GL_STENCIL_BUFFER_BIT);
gGL.setColorMask(true, false);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
@@ -5182,7 +5219,6 @@ void LLPipeline::renderDebug()
glPointSize(1.f);
}
-
// Debug stuff.
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -5236,6 +5272,12 @@ void LLPipeline::renderDebug()
visible_selected_groups.clear();
+ //draw reflection probes and links between them
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only)
+ {
+ mReflectionMapManager.renderDebug();
+ }
+
gUIProgram.bind();
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
@@ -5660,17 +5702,28 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
mMaterialsPool = new_poolp;
}
break;
- case LLDrawPool::POOL_ALPHA:
- if( mAlphaPool )
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ if( mAlphaPoolPreWater )
{
llassert(0);
- LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << LL_ENDL;
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pre-water pool" << LL_ENDL;
}
else
{
- mAlphaPool = (LLDrawPoolAlpha*) new_poolp;
+ mAlphaPoolPreWater = (LLDrawPoolAlpha*) new_poolp;
}
break;
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ if (mAlphaPoolPostWater)
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha post-water pool" << LL_ENDL;
+ }
+ else
+ {
+ mAlphaPoolPostWater = (LLDrawPoolAlpha*)new_poolp;
+ }
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -5724,6 +5777,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_PBR_OPAQUE:
+ if( mPBROpaquePool )
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Opaque Pool" << LL_ENDL;
+ }
+ else
+ {
+ mPBROpaquePool = new_poolp;
+ }
+ break;
+
default:
llassert(0);
LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL;
@@ -5816,10 +5881,15 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mMaterialsPool = NULL;
break;
- case LLDrawPool::POOL_ALPHA:
- llassert( poolp == mAlphaPool );
- mAlphaPool = NULL;
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ llassert( poolp == mAlphaPoolPreWater );
+ mAlphaPoolPreWater = nullptr;
break;
+
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ llassert(poolp == mAlphaPoolPostWater);
+ mAlphaPoolPostWater = nullptr;
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -5840,6 +5910,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mGroundPool = NULL;
break;
+ case LLDrawPool::POOL_PBR_OPAQUE:
+ llassert( poolp == mPBROpaquePool );
+ mPBROpaquePool = NULL;
+ break;
+
default:
llassert(0);
LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL;
@@ -5956,6 +6031,7 @@ void LLPipeline::setupAvatarLights(bool for_edit)
static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
F32 inten = light->getLightIntensity();
if (inten < .001f)
{
@@ -5979,9 +6055,10 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
void LLPipeline::calcNearbyLights(LLCamera& camera)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
assertInitialized();
- if (LLPipeline::sReflectionRender)
+ if (LLPipeline::sReflectionRender || gCubeSnapshot)
{
return;
}
@@ -6164,6 +6241,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
void LLPipeline::setupHWLights(LLDrawPool* pool)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
assertInitialized();
LLEnvironment& environment = LLEnvironment::instance();
@@ -6171,7 +6249,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
// Ambient
LLColor4 ambient = psky->getTotalAmbient();
- gGL.setAmbientLightColor(ambient);
+
+ gGL.setAmbientLightColor(ambient);
bool sun_up = environment.getIsSunUp();
bool moon_up = environment.getIsMoonUp();
@@ -6309,6 +6388,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setDiffuse(light_color);
light_state->setAmbient(LLColor4::black);
light_state->setConstantAttenuation(0.f);
+ light_state->setSize(light->getLightRadius() * 1.5f);
+ light_state->setFalloff(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
+
if (sRenderDeferred)
{
light_state->setLinearAttenuation(linatten);
@@ -6725,15 +6807,6 @@ void LLPipeline::toggleRenderType(U32 type)
//static
void LLPipeline::toggleRenderTypeControl(U32 type)
{
- U32 bit = (1<<type);
- if (gPipeline.hasRenderType(type))
- {
- LL_INFOS() << "Toggling render type mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Toggling render type mask " << std::hex << bit << " on" << std::dec << LL_ENDL;
- }
gPipeline.toggleRenderType(type);
}
@@ -6979,7 +7052,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, TRUE, face_hit, &position, NULL, NULL, NULL);
if (hit)
{
drawable = hit;
@@ -7007,6 +7080,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start,
LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
bool pick_transparent,
bool pick_rigged,
+ bool pick_unselectable,
S32* face_hit,
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
@@ -7040,7 +7114,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(j);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -7097,7 +7171,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
LLVector4a delta;
@@ -7185,7 +7259,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, c
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
if (part)
{
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, face_hit, intersection, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, TRUE, face_hit, intersection, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -7260,6 +7334,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
mResetVertexBuffers = false;
mCubeVB = NULL;
+ mDeferredVB = NULL;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -7293,10 +7368,11 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPathingLib::getInstance()->cleanupVBOManager();
}
LLVOPartGroup::destroyGL();
+ gGL.resetVertexBuffer();
SUBSYSTEM_CLEANUP(LLVertexBuffer);
- if (LLVertexBuffer::sGLCount > 0)
+ if (LLVertexBuffer::sGLCount != 0)
{
LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
}
@@ -7317,6 +7393,10 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+ gGL.initVertexBuffer();
+
+ mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
+ mDeferredVB->allocateBuffer(8, 0, true);
LLVOPartGroup::restoreGL();
}
@@ -7480,15 +7560,12 @@ void LLPipeline::renderFinalize()
assertInitialized();
- if (gUseWireframe)
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
-
LLVector2 tc1(0, 0);
- LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2);
+ LLVector2 tc2((F32) mRT->screen.getWidth() * 2, (F32) mRT->screen.getHeight() * 2);
LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+ LL_PROFILE_GPU_ZONE("renderFinalize");
+
gGL.color4f(1, 1, 1, 1);
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
@@ -7508,8 +7585,79 @@ void LLPipeline::renderFinalize()
gGL.setColorMask(true, true);
glClearColor(0, 0, 0, 0);
+ if (!gCubeSnapshot)
+ {
+ // gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ {
+ LL_PROFILE_GPU_ZONE("gamma correct");
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLRenderTarget* screen_target = &mRT->screen;
+
+ LLVector2 tc1(0, 0);
+ LLVector2 tc2((F32)screen_target->getWidth() * 2, (F32)screen_target->getHeight() * 2);
+
+ screen_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, screen_target->getUsage());
+ if (channel > -1)
+ {
+ screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_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(screen_target->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ screen_target->flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ LLVertexBuffer::unbind();
+
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ // Render debugging beacons.
+ gObjectList.renderObjectBeacons();
+ gObjectList.resetObjectBeacons();
+ gSky.addSunMoonBeacons();
+ }
+ }
+
if (sRenderGlow)
{
+ LL_PROFILE_GPU_ZONE("glow");
mGlow[2].bindTarget();
mGlow[2].clear();
@@ -7534,7 +7682,7 @@ void LLPipeline::renderFinalize()
gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
+ mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
gGL.color4f(1, 1, 1, 1);
gPipeline.enableLightsFullbright();
@@ -7550,7 +7698,7 @@ void LLPipeline::renderFinalize()
gGL.end();
- gGL.getTexUnit(0)->unbind(mScreen.getUsage());
+ gGL.getTexUnit(0)->unbind(mRT->screen.getUsage());
mGlow[2].flush();
@@ -7628,7 +7776,7 @@ void LLPipeline::renderFinalize()
gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight());
+ tc2.setVec((F32) mRT->screen.getWidth(), (F32) mRT->screen.getHeight());
gGL.flush();
@@ -7636,17 +7784,18 @@ void LLPipeline::renderFinalize()
if (LLPipeline::sRenderDeferred)
{
-
bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField;
+ RenderDepthOfField &&
+ !gCubeSnapshot;
- bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
gViewerWindow->setup3DViewport();
if (dof_enabled)
{
+ LL_PROFILE_GPU_ZONE("dof");
LLGLSLShader *shader = &gDeferredPostProgram;
LLGLDisable blend(GL_BLEND);
@@ -7682,7 +7831,7 @@ void LLPipeline::renderFinalize()
LLVector4a result;
result.clear();
- gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result);
+ gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result);
focus_point.set(result.getF32ptr());
}
@@ -7731,7 +7880,7 @@ void LLPipeline::renderFinalize()
const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
- // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
+ // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
@@ -7751,15 +7900,15 @@ void LLPipeline::renderFinalize()
F32 magnification = focal_length / (subject_distance - focal_length);
{ // build diffuse+bloom+CoF
- mDeferredLight.bindTarget();
+ mRT->deferredLight.bindTarget();
shader = &gDeferredCoFProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel);
+ mRT->screen.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
@@ -7782,23 +7931,23 @@ void LLPipeline::renderFinalize()
gGL.end();
unbindDeferredShader(*shader);
- mDeferredLight.flush();
+ mRT->deferredLight.flush();
}
- U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale);
- U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale);
+ U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
+ U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
{ // perform DoF sampling at half-res (preserve alpha channel)
- mScreen.bindTarget();
+ mRT->screen.bindTarget();
glViewport(0, 0, dof_width, dof_height);
gGL.setColorMask(true, false);
shader = &gDeferredPostProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
if (channel > -1)
{
- mDeferredLight.bindTexture(0, channel);
+ mRT->deferredLight.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
@@ -7817,15 +7966,15 @@ void LLPipeline::renderFinalize()
gGL.end();
unbindDeferredShader(*shader);
- mScreen.flush();
+ mRT->screen.flush();
gGL.setColorMask(true, true);
}
{ // combine result based on alpha
if (multisample)
{
- mDeferredLight.bindTarget();
- glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+ mRT->deferredLight.bindTarget();
+ glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight());
}
else
{
@@ -7839,10 +7988,10 @@ void LLPipeline::renderFinalize()
shader = &gDeferredDoFCombineProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel);
+ mRT->screen.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
@@ -7866,24 +8015,25 @@ void LLPipeline::renderFinalize()
if (multisample)
{
- mDeferredLight.flush();
+ mRT->deferredLight.flush();
}
}
}
else
{
+ LL_PROFILE_GPU_ZONE("no dof");
if (multisample)
{
- mDeferredLight.bindTarget();
+ mRT->deferredLight.bindTarget();
}
LLGLSLShader *shader = &gDeferredPostNoDoFProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel);
+ mRT->screen.bindTexture(0, channel);
}
gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -7902,17 +8052,18 @@ void LLPipeline::renderFinalize()
if (multisample)
{
- mDeferredLight.flush();
+ mRT->deferredLight.flush();
}
}
if (multisample)
{
+ LL_PROFILE_GPU_ZONE("aa");
// bake out texture2D with RGBL for FXAA shader
- mFXAABuffer.bindTarget();
+ mRT->fxaaBuffer.bindTarget();
- S32 width = mScreen.getWidth();
- S32 height = mScreen.getHeight();
+ S32 width = mRT->screen.getWidth();
+ S32 height = mRT->screen.getHeight();
glViewport(0, 0, width, height);
LLGLSLShader *shader = &gGlowCombineFXAAProgram;
@@ -7920,10 +8071,10 @@ void LLPipeline::renderFinalize()
shader->bind();
shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
if (channel > -1)
{
- mDeferredLight.bindTexture(0, channel);
+ mRT->deferredLight.bindTexture(0, channel);
}
gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -7934,18 +8085,18 @@ void LLPipeline::renderFinalize()
gGL.flush();
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
shader->unbind();
- mFXAABuffer.flush();
+ mRT->fxaaBuffer.flush();
shader = &gFXAAProgram;
shader->bind();
- channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
+ channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
if (channel > -1)
{
- mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
}
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
@@ -7954,8 +8105,8 @@ void LLPipeline::renderFinalize()
gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- F32 scale_x = (F32) width / mFXAABuffer.getWidth();
- F32 scale_y = (F32) height / mFXAABuffer.getHeight();
+ F32 scale_x = (F32) width / mRT->fxaaBuffer.getWidth();
+ F32 scale_y = (F32) height / mRT->fxaaBuffer.getHeight();
shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
@@ -7973,6 +8124,7 @@ void LLPipeline::renderFinalize()
shader->unbind();
}
}
+#if 0 // DEPRECATED
else // not deferred
{
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
@@ -8006,16 +8158,16 @@ void LLPipeline::renderFinalize()
gGlowCombineProgram.bind();
gGL.getTexUnit(0)->bind(&mGlow[1]);
- gGL.getTexUnit(1)->bind(&mScreen);
+ gGL.getTexUnit(1)->bind(&mRT->screen);
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
buff->setBuffer(mask);
buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
gGlowCombineProgram.unbind();
}
-
+#endif
gGL.setSceneBlendType(LLRender::BT_ALPHA);
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
@@ -8049,12 +8201,12 @@ void LLPipeline::renderFinalize()
gSplatTextureRectProgram.unbind();
}
- if (LLRenderTarget::sUseFBO)
- { // copy depth buffer from mScreen to framebuffer
- LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 0, 0,
- mScreen.getWidth(), mScreen.getHeight(),
+ /*if (LLRenderTarget::sUseFBO && !gCubeSnapshot)
+ { // copy depth buffer from mRT->screen to framebuffer
+ LLRenderTarget::copyContentsToFramebuffer(mRT->screen, 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), 0, 0,
+ mRT->screen.getWidth(), mRT->screen.getHeight(),
GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- }
+ }*/
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
@@ -8070,37 +8222,59 @@ void LLPipeline::renderFinalize()
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-
- LLRenderTarget* deferred_target = &mDeferredScreen;
- LLRenderTarget* deferred_depth_target = &mDeferredDepth;
- LLRenderTarget* deferred_light_target = &mDeferredLight;
+ LL_PROFILE_GPU_ZONE("bindDeferredShader");
+ LLRenderTarget* deferred_target = &mRT->deferredScreen;
+ //LLRenderTarget* deferred_depth_target = &mRT->deferredDepth;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
shader.bind();
S32 channel = 0;
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT); // frag_data[0]
}
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT); // frag_data[1]
}
channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT); // frag_data[2]
}
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
+ if (channel > -1)
+ {
+ deferred_target->bindTexture(3, channel, LLTexUnit::TFO_POINT); // frag_data[3]
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_BRDF_LUT, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ mPbrBrdfLut.bindTexture(0, channel);
+ }
+
+
+#if 0
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
if (channel > -1)
{
gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE);
stop_glerror();
}
+#else
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+ stop_glerror();
+ }
+#endif
glh::matrix4f projection = get_current_projection();
glh::matrix4f inv_proj = projection.inverse();
@@ -8155,7 +8329,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
for (U32 i = 0; i < 4; i++)
{
- LLRenderTarget* shadow_target = getShadowTarget(i);
+ LLRenderTarget* shadow_target = getSunShadowTarget(i);
if (shadow_target)
{
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE);
@@ -8163,39 +8337,39 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
if (channel > -1)
{
stop_glerror();
- gGL.getTexUnit(channel)->bind(getShadowTarget(i), TRUE);
+ gGL.getTexUnit(channel)->bind(getSunShadowTarget(i), TRUE);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
stop_glerror();
}
}
}
- for (U32 i = 4; i < 6; i++)
- {
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i);
- stop_glerror();
- if (channel > -1)
- {
- stop_glerror();
- LLRenderTarget* shadow_target = getShadowTarget(i);
- if (shadow_target)
- {
- gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
- stop_glerror();
- }
- }
- }
+ for (U32 i = 4; i < 6; i++)
+ {
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0 + i);
+ stop_glerror();
+ if (channel > -1)
+ {
+ stop_glerror();
+ LLRenderTarget* shadow_target = getSpotShadowTarget(i-4);
+ if (shadow_target)
+ {
+ gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ stop_glerror();
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+ stop_glerror();
+ }
+ }
+ }
stop_glerror();
@@ -8222,16 +8396,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
{
cube_map->enable(channel);
cube_map->bind();
- F32* m = gGLModelView;
-
- F32 mat[] = { m[0], m[1], m[2],
- m[4], m[5], m[6],
- m[8], m[9], m[10] };
-
- shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
}
+
+ F32* m = gGLModelView;
+
+ F32 mat[] = { m[0], m[1], m[2],
+ m[4], m[5], m[6],
+ m[8], m[9], m[10] };
+
+ shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
}
+ bindReflectionProbes(shader);
+
if (gAtmosphere)
{
// bind precomputed textures necessary for calculating sun and sky luminance
@@ -8260,7 +8437,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
}
}
- shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
+ /*if (gCubeSnapshot)
+ { // we only really care about the first two values, but the shader needs increasing separation between clip planes
+ shader.uniform4f(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1.f, 64.f, 128.f, 256.f);
+ }
+ else*/
+ {
+ shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
+ }
shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize);
@@ -8295,8 +8479,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV);
shader.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.mV);
- shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mShadow[0].getWidth(), mShadow[0].getHeight());
- shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight());
shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
@@ -8306,8 +8490,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
}
- shader.uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuse.mV);
- shader.uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV);
+ shader.uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuse.mV);
+ shader.uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV);
LLEnvironment& environment = LLEnvironment::instance();
LLSettingsSky::ptr_t sky = environment.getCurrentSky();
@@ -8329,21 +8513,25 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f)
return v;
}
-void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
+void LLPipeline::renderDeferredLighting()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("renderDeferredLighting");
if (!sCull)
{
return;
}
- LLRenderTarget *deferred_target = &mDeferredScreen;
- LLRenderTarget *deferred_depth_target = &mDeferredDepth;
- LLRenderTarget *deferred_light_target = &mDeferredLight;
+ LLRenderTarget *screen_target = &mRT->screen;
+ //LLRenderTarget *deferred_target = &mRT->deferredScreen;
+ //LLRenderTarget *deferred_depth_target = &mRT->deferredDepth;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
LLViewerCamera *camera = LLViewerCamera::getInstance();
+
+#if 0
{
LLGLDepthTest depth(GL_TRUE);
deferred_depth_target->copyContents(*deferred_target,
@@ -8358,8 +8546,9 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
}
+#endif
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
{
@@ -8367,7 +8556,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
}
// ati doesn't seem to love actually using the stencil buffer on FBO's
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
// glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
// glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
@@ -8406,6 +8595,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
if (RenderDeferredSSAO || RenderShadowDetail > 0)
{
+ LL_PROFILE_GPU_ZONE("sun program");
deferred_light_target->bindTarget();
{ // paint shadow/SSAO light map (direct lighting lightmap)
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - sun shadow");
@@ -8453,66 +8643,79 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
}
if (RenderDeferredSSAO)
- { // soften direct lighting lightmap
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow");
- // blur lightmap
- screen_target->bindTarget();
- glClearColor(1, 1, 1, 1);
- screen_target->clear(GL_COLOR_BUFFER_BIT);
- glClearColor(0, 0, 0, 0);
+ {
+ /*if (gCubeSnapshot)
+ { // SSAO and shadows disabled in reflection maps
+ deferred_light_target->bindTarget();
+ glClearColor(1, 1, 1, 1);
+ deferred_light_target->clear();
+ glClearColor(0, 0, 0, 0);
+ deferred_light_target->flush();
+ }
+ else*/
+ {
+ // soften direct lighting lightmap
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow");
+ LL_PROFILE_GPU_ZONE("soften shadow");
+ // blur lightmap
+ screen_target->bindTarget();
+ glClearColor(1, 1, 1, 1);
+ screen_target->clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0, 0, 0, 0);
- bindDeferredShader(gDeferredBlurLightProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- LLVector3 go = RenderShadowGaussian;
- const U32 kern_length = 4;
- F32 blur_size = RenderShadowBlurSize;
- F32 dist_factor = RenderShadowBlurDistFactor;
+ bindDeferredShader(gDeferredBlurLightProgram);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ LLVector3 go = RenderShadowGaussian;
+ const U32 kern_length = 4;
+ F32 blur_size = RenderShadowBlurSize;
+ F32 dist_factor = RenderShadowBlurDistFactor;
- // sample symmetrically with the middle sample falling exactly on 0.0
- F32 x = 0.f;
+ // sample symmetrically with the middle sample falling exactly on 0.0
+ F32 x = 0.f;
- LLVector3 gauss[32]; // xweight, yweight, offset
+ LLVector3 gauss[32]; // xweight, yweight, offset
- for (U32 i = 0; i < kern_length; i++)
- {
- gauss[i].mV[0] = llgaussian(x, go.mV[0]);
- gauss[i].mV[1] = llgaussian(x, go.mV[1]);
- gauss[i].mV[2] = x;
- x += 1.f;
- }
+ for (U32 i = 0; i < kern_length; i++)
+ {
+ gauss[i].mV[0] = llgaussian(x, go.mV[0]);
+ gauss[i].mV[1] = llgaussian(x, go.mV[1]);
+ gauss[i].mV[2] = x;
+ x += 1.f;
+ }
- gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
- gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
- gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
- gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f));
+ gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
+ gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
+ gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
+ gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f));
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
- }
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
- screen_target->flush();
- unbindDeferredShader(gDeferredBlurLightProgram);
+ screen_target->flush();
+ unbindDeferredShader(gDeferredBlurLightProgram);
- bindDeferredShader(gDeferredBlurLightProgram, screen_target);
+ bindDeferredShader(gDeferredBlurLightProgram, screen_target);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- deferred_light_target->bindTarget();
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ deferred_light_target->bindTarget();
- gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
+ gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
+ deferred_light_target->flush();
+ unbindDeferredShader(gDeferredBlurLightProgram);
}
- deferred_light_target->flush();
- unbindDeferredShader(gDeferredBlurLightProgram);
}
stop_glerror();
@@ -8533,11 +8736,23 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics");
+ LL_PROFILE_GPU_ZONE("atmospherics");
bindDeferredShader(soften_shader);
LLEnvironment &environment = LLEnvironment::instance();
soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+ soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+
+ if (!LLPipeline::sUnderWaterRender && LLPipeline::sRenderPBR)
+ {
+ soften_shader.bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, LLViewerFetchedTexture::sDefaultIrradiancePBRp); // PBR: irradiance
+ }
+
+ if(LLPipeline::sRenderPBR)
+ {
+ LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis();
+ soften_shader.uniform3fv(LLShaderMgr::DEFERRED_VIEW_DIR, 1, cameraAtAxis.mV);
+ }
{
LLGLDepthTest depth(GL_FALSE);
@@ -8563,9 +8778,10 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
}
+#if 0
{ // render non-deferred geometry (fullbright, alpha, etc)
LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
gPipeline.pushRenderTypeMask();
@@ -8578,8 +8794,9 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
gPipeline.popRenderTypeMask();
}
+#endif
- bool render_local = RenderLocalLights;
+ bool render_local = RenderLocalLights; // && !gCubeSnapshot;
if (render_local)
{
@@ -8588,9 +8805,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLDrawable::drawable_list_t spot_lights;
LLDrawable::drawable_list_t fullscreen_spot_lights;
- for (U32 i = 0; i < 2; i++)
+ if (!gCubeSnapshot)
{
- mTargetShadowSpotLight[i] = NULL;
+ for (U32 i = 0; i < 2; i++)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
}
std::list<LLVector4> light_colors;
@@ -8599,11 +8819,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - local lights");
+ LL_PROFILE_GPU_ZONE("local lights");
bindDeferredShader(gDeferredLightProgram);
if (mCubeVB.isNull())
{
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
@@ -8705,6 +8926,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
if (!spot_lights.empty())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - projectors");
+ LL_PROFILE_GPU_ZONE("projectors");
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bindDeferredShader(gDeferredSpotLightProgram);
@@ -8751,7 +8973,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - fullscreen lights");
LLGLDepthTest depth(GL_FALSE);
-
+ LL_PROFILE_GPU_ZONE("fullscreen lights");
// full screen blit
gGL.pushMatrix();
gGL.loadIdentity();
@@ -8836,69 +9058,14 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
gGL.setColorMask(true, true);
}
- screen_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) screen_target->getWidth() * 2, (F32) screen_target->getHeight() * 2);
-
- screen_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, screen_target->getUsage());
- if (channel > -1)
- {
- screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
-
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_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(screen_target->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- screen_target->flush();
- }
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- screen_target->bindTarget();
-
{ // render non-deferred geometry (alpha, fullbright, glow)
LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
pushRenderTypeMask();
andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER,
+ LLPipeline::RENDER_TYPE_ALPHA_POST_WATER,
LLPipeline::RENDER_TYPE_FULLBRIGHT,
LLPipeline::RENDER_TYPE_VOLUME,
LLPipeline::RENDER_TYPE_GLOW,
@@ -8920,30 +9087,13 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLPipeline::RENDER_TYPE_CONTROL_AV,
LLPipeline::RENDER_TYPE_ALPHA_MASK,
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_WATER,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
popRenderTypeMask();
}
- {
- // render highlights, etc.
- renderHighlights();
- mHighlightFaces.clear();
-
- renderDebug();
-
- LLVertexBuffer::unbind();
-
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- // Render debugging beacons.
- gObjectList.renderObjectBeacons();
- gObjectList.resetObjectBeacons();
- gSky.addSunMoonBeacons();
- }
- }
-
screen_target->flush();
}
@@ -9037,6 +9187,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
}
+ //if (!gCubeSnapshot)
{
LLDrawable* potential = drawablep;
//determine if this is a good light for casting shadows
@@ -9088,15 +9239,18 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
- LLRenderTarget* deferred_target = &mDeferredScreen;
- LLRenderTarget* deferred_depth_target = &mDeferredDepth;
- LLRenderTarget* deferred_light_target = &mDeferredLight;
+ LLRenderTarget* deferred_target = &mRT->deferredScreen;
+ //LLRenderTarget* deferred_depth_target = &mRT->deferredDepth;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
stop_glerror();
shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT);
+ //shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage());
shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
@@ -9105,7 +9259,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}
@@ -9113,7 +9267,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}
@@ -9129,350 +9283,74 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
cube_map->disable();
}
}
+
+ unbindReflectionProbes(shader);
+
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(0)->activate();
shader.unbind();
}
-inline float sgn(float a)
+void LLPipeline::setEnvMat(LLGLSLShader& shader)
{
- if (a > 0.0F) return (1.0F);
- if (a < 0.0F) return (-1.0F);
- return (0.0F);
+ F32* m = gGLModelView;
+
+ F32 mat[] = { m[0], m[1], m[2],
+ m[4], m[5], m[6],
+ m[8], m[9], m[10] };
+
+ shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
}
-void LLPipeline::generateWaterReflection(LLCamera& camera_in)
+void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-
- if (!assertInitialized())
+ if (!sReflectionProbesEnabled)
{
return;
}
- if (LLPipeline::sWaterReflections && LLDrawPoolWater::sNeedsReflectionUpdate)
+ S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ bool bound = false;
+ if (channel > -1 && mReflectionMapManager.mTexture.notNull())
{
- //disable occlusion culling for reflection/refraction passes (save setting to restore later)
- S32 occlude = LLPipeline::sUseOcclusion;
- LLPipeline::sUseOcclusion = 0;
-
- bool skip_avatar_update = false;
- if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
- {
- skip_avatar_update = true;
- }
-
- LLCamera camera = camera_in;
- camera.setFar(camera_in.getFar() * 0.75f);
-
- bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
-
- LLPipeline::sReflectionRender = true;
-
- gPipeline.pushRenderTypeMask();
-
- glh::matrix4f saved_modelview = get_current_modelview();
- glh::matrix4f saved_projection = get_current_projection();
- glh::matrix4f mat;
-
- S32 reflection_detail = RenderReflectionDetail;
-
- F32 water_height = gAgent.getRegion()->getWaterHeight();
- F32 camera_height = camera_in.getOrigin().mV[VZ];
- F32 distance_to_water = (water_height < camera_height) ? (camera_height - water_height) : (water_height - camera_height);
-
- LLVector3 reflection_offset = LLVector3(0, 0, distance_to_water * 2.0f);
- LLVector3 camera_look_at = camera_in.getAtAxis();
- LLVector3 reflection_look_at = LLVector3(camera_look_at.mV[VX], camera_look_at.mV[VY], -camera_look_at.mV[VZ]);
- LLVector3 reflect_origin = camera_in.getOrigin() - reflection_offset;
- LLVector3 reflect_interest_point = reflect_origin + (reflection_look_at * 5.0f);
-
- camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point);
-
- //plane params
- LLPlane plane;
- LLVector3 pnorm;
-
- if (camera_is_underwater)
- {
- //camera is below water, cull above water
- pnorm.setVec(0, 0, 1);
- }
- else
- {
- //camera is above water, cull below water
- pnorm = LLVector3(0, 0, -1);
- }
-
- plane.setVec(LLVector3(0, 0, water_height), pnorm);
-
- if (!camera_is_underwater)
- {
- //generate planar reflection map
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
-
- mat.set_scale(glh::vec3f(1, 1, -1));
- mat.set_translate(glh::vec3f(0,0,water_height*2.f));
- mat = saved_modelview * mat;
-
-
- mReflectionModelView = mat;
-
- set_current_modelview(mat);
- gGL.loadMatrix(mat.m);
-
- LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
-
- glh::vec3f origin(0, 0, 0);
- glh::matrix4f inv_mat = mat.inverse();
- inv_mat.mult_matrix_vec(origin);
-
- camera.setOrigin(origin.v);
-
- glCullFace(GL_FRONT);
-
- if (LLDrawPoolWater::sNeedsReflectionUpdate)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- glClearColor(0,0,0,0);
- mWaterRef.bindTarget();
-
- gGL.setColorMask(true, true);
- mWaterRef.clear();
- gGL.setColorMask(true, false);
- mWaterRef.getViewport(gGLViewport);
-
- //initial sky pass (no user clip plane)
- //mask out everything but the sky
- gPipeline.pushRenderTypeMask();
- {
- if (reflection_detail >= WATER_REFLECT_MINIMAL)
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
- }
- else
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
- }
-
- updateCull(camera, mSky);
- stateSort(camera, mSky);
- renderGeom(camera, TRUE);
- }
- gPipeline.popRenderTypeMask();
-
- if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
- {
- gPipeline.pushRenderTypeMask();
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
-
- if (reflection_detail > WATER_REFLECT_MINIMAL)
- { //mask out selected geometry based on reflection detail
- if (reflection_detail < WATER_REFLECT_EVERYTHING)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
- if (reflection_detail < WATER_REFLECT_AVATARS)
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_CONTROL_AV,
- END_RENDER_TYPES);
- if (reflection_detail < WATER_REFLECT_STATIC_OBJECTS)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
- }
- }
- }
-
- LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);
- LLGLDisable cull(GL_CULL_FACE);
- updateCull(camera, mReflectedObjects, &plane);
- stateSort(camera, mReflectedObjects);
- renderGeom(camera);
- }
- }
- gPipeline.popRenderTypeMask();
- }
-
- mWaterRef.flush();
- }
-
- glCullFace(GL_BACK);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- set_current_modelview(saved_modelview);
- }
-
- camera.setOrigin(camera_in.getOrigin());
- //render distortion map
- static bool last_update = true;
- if (last_update)
- {
- gPipeline.pushRenderTypeMask();
-
- camera.setFar(camera_in.getFar());
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- END_RENDER_TYPES);
-
- // intentionally inverted so that distortion map contents (objects under the water when we're above it)
- // will properly include water fog effects
- LLPipeline::sUnderWaterRender = !camera_is_underwater;
-
- if (LLPipeline::sUnderWaterRender)
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- END_RENDER_TYPES);
- }
- LLViewerCamera::updateFrustumPlanes(camera);
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if (LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsDistortionUpdate)
- {
- LLPipeline::sDistortionRender = true;
-
- LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
- glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
-
- // HACK FIX -- pretend underwater camera is the world camera to fix weird visibility artifacts
- // during distortion render (doesn't break main render because the camera is the same perspective
- // as world camera and occlusion culling is disabled for this pass)
- //LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- mWaterDis.bindTarget();
- mWaterDis.getViewport(gGLViewport);
-
- gGL.setColorMask(true, true);
- mWaterDis.clear();
- gGL.setColorMask(true, false);
-
- F32 water_dist = water_height;
-
- //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself,
- // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map
- LLPlane plane;
-
- if (camera_is_underwater)
- {
- //nudge clip plane below water to avoid visible holes in objects intersecting water surface
- water_dist /= LLPipeline::sDistortionWaterClipPlaneMargin;
- //camera is below water, clip plane points up
- pnorm.setVec(0, 0, -1);
- }
- else
- {
- //nudge clip plane above water to avoid visible holes in objects intersecting water surface
- water_dist *= LLPipeline::sDistortionWaterClipPlaneMargin;
- //camera is above water, clip plane points down
- pnorm = LLVector3(0, 0, 1);
- }
-
- plane.setVec(LLVector3(0, 0, water_dist), pnorm);
-
- LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);
-
- gGL.setColorMask(true, true);
- mWaterDis.clear();
- gGL.setColorMask(true, false);
-
- if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
- {
- updateCull(camera, mRefractedObjects, &plane);
- stateSort(camera, mRefractedObjects);
- renderGeom(camera);
- }
-
- gUIProgram.bind();
-
- LLWorld::getInstance()->renderPropertyLines();
-
- gUIProgram.unbind();
-
- mWaterDis.flush();
- }
-
- LLPipeline::sDistortionRender = false;
-
- gPipeline.popRenderTypeMask();
- }
- last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
-
- gPipeline.popRenderTypeMask();
-
- LLPipeline::sUnderWaterRender = false;
- LLPipeline::sReflectionRender = false;
+ mReflectionMapManager.mTexture->bind(channel);
+ bound = true;
+ }
- LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
- LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
+ channel = shader.enableTexture(LLShaderMgr::IRRADIANCE_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ if (channel > -1 && mReflectionMapManager.mIrradianceMaps.notNull())
+ {
+ mReflectionMapManager.mIrradianceMaps->bind(channel);
+ bound = true;
+ }
- if (!LLRenderTarget::sUseFBO)
- {
- glClear(GL_DEPTH_BUFFER_BIT);
- }
- glClearColor(0.f, 0.f, 0.f, 0.f);
- gViewerWindow->setup3DViewport();
+ if (bound)
+ {
+ mReflectionMapManager.setUniforms();
- LLGLState::checkStates();
+ setEnvMat(shader);
+ }
+}
- if (!skip_avatar_update)
+void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader)
+{
+ S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP);
+ if (channel > -1 && mReflectionMapManager.mTexture.notNull())
+ {
+ mReflectionMapManager.mTexture->unbind();
+ if (channel == 0)
{
- gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ gGL.getTexUnit(channel)->enable(LLTexUnit::TT_TEXTURE);
}
-
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- // restore occlusion culling
- LLPipeline::sUseOcclusion = occlude;
}
- else
- {
- // Initial sky pass is still needed even if water reflection is not rendering
- bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
- if (!camera_is_underwater)
- {
- gPipeline.pushRenderTypeMask();
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
+}
- LLCamera camera = camera_in;
- camera.setFar(camera_in.getFar() * 0.75f);
- updateCull(camera, mSky);
- stateSort(camera, mSky);
- renderGeom(camera, TRUE);
- }
- gPipeline.popRenderTypeMask();
- }
- }
+inline float sgn(float a)
+{
+ if (a > 0.0F) return (1.0F);
+ if (a < 0.0F) return (-1.0F);
+ return (0.0F);
}
glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
@@ -9555,7 +9433,7 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbri
void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER);
-
+ LL_PROFILE_GPU_ZONE("renderShadow");
//disable occlusion culling for shadow passes (save setting to restore later)
S32 occlude = LLPipeline::sUseOcclusion;
if (!use_occlusion)
@@ -9577,20 +9455,22 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_NORMMAP,
LLRenderPass::PASS_NORMMAP_EMISSIVE,
LLRenderPass::PASS_NORMSPEC,
- LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE
};
LLGLEnable cull(GL_CULL_FACE);
//enable depth clamping if available
- LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+ //LLGLEnable depth_clamp(GL_DEPTH_CLAMP);
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
- LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1];
+ LLRenderTarget& occlusion_target = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
+ mSpotShadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
+ mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
occlusion_target.bindTarget();
updateCull(shadow_cam, result);
@@ -9642,7 +9522,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
-
+ LL_PROFILE_GPU_ZONE("shadow simple");
gGL.getTexUnit(0)->disable();
for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i)
{
@@ -9659,7 +9539,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
if (use_shader)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom");
gDeferredShadowProgram.unbind();
renderGeomShadow(shadow_cam);
@@ -9668,14 +9548,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
else
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom");
renderGeomShadow(shadow_cam);
}
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA);
-
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha");
+ LL_PROFILE_GPU_ZONE("shadow alpha");
for (int i = 0; i < 2; ++i)
{
bool rigged = i == 1;
@@ -9690,19 +9570,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLVertexBuffer::MAP_TEXTURE_INDEX;
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked");
renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged);
}
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend");
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
renderAlphaObjects(mask, TRUE, TRUE, rigged);
}
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked");
gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
@@ -9711,7 +9591,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass");
gDeferredTreeShadowProgram.bind(rigged);
if (i == 0)
{
@@ -9724,6 +9604,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, no_idx_mask, true, false, rigged);
renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, no_idx_mask, true, false, rigged);
renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged);
+ renderMaskedObjects(LLRenderPass::PASS_PBR_OPAQUE, no_idx_mask, true, false, rigged);
}
}
}
@@ -9734,9 +9615,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
- LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1];
+ LLRenderTarget& occlusion_source = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
+ mSpotShadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
+ mRT->shadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
- doOcclusion(shadow_cam, occlusion_source, occlusion_target);
+ if (occlude > 1)
+ {
+ doOcclusion(shadow_cam, occlusion_source, occlusion_target);
+ }
if (use_shader)
{
@@ -9957,7 +9843,8 @@ void LLPipeline::generateHighlight(LLCamera& camera)
{
mHighlightSet.insert(HighlightItem(mHighlightObject));
}
-
+ llassert(!gCubeSnapshot);
+
if (!mHighlightSet.empty())
{
F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime;
@@ -10005,9 +9892,16 @@ void LLPipeline::generateHighlight(LLCamera& camera)
}
}
-LLRenderTarget* LLPipeline::getShadowTarget(U32 i)
+LLRenderTarget* LLPipeline::getSunShadowTarget(U32 i)
{
- return &mShadow[i];
+ llassert(i < 4);
+ return &mRT->shadow[i];
+}
+
+LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i)
+{
+ llassert(i < 2);
+ return &mSpotShadow[i];
}
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
@@ -10021,6 +9915,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
+ LL_PROFILE_GPU_ZONE("generateSunShadow");
bool skip_avatar_update = false;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
@@ -10045,6 +9940,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
pushRenderTypeMask();
andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER,
+ LLPipeline::RENDER_TYPE_ALPHA_POST_WATER,
LLPipeline::RENDER_TYPE_GRASS,
LLPipeline::RENDER_TYPE_FULLBRIGHT,
LLPipeline::RENDER_TYPE_BUMP,
@@ -10103,6 +10000,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED,
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED,
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE,
+ LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE_RIGGED,
END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -10132,6 +10031,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
clip = RenderShadowOrthoClipPlanes;
mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
+ //if (gCubeSnapshot)
+ { //always do a single 64m shadow in reflection maps
+ mSunClipPlanes.set(64.f, 128.f, 256.f);
+ mSunOrthoClipPlanes.set(64.f, 128.f, 256.f);
+ }
+
//currently used for amount to extrude frusta corners for constructing shadow frusta
//LLVector3 n = RenderShadowNearDist;
//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
@@ -10248,28 +10153,41 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
// convenience array of 4 near clip plane distances
F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
-
if (mSunDiffuse == LLColor4::black)
- { //sun diffuse is totally black, shadows don't matter
+ { //sun diffuse is totally shadows don't matter
LLGLDepthTest depth(GL_TRUE);
for (S32 j = 0; j < 4; j++)
{
- mShadow[j].bindTarget();
- mShadow[j].clear();
- mShadow[j].flush();
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].clear();
+ mRT->shadow[j].flush();
}
}
else
{
- for (S32 j = 0; j < 4; j++)
+ /*if (gCubeSnapshot)
+ {
+ // do one shadow split for cube snapshots, clear the rest
+ mSunClipPlanes.set(64.f, 64.f, 64.f);
+ dist[1] = dist[2] = dist[3] = dist[4] = 64.f;
+ for (S32 j = 1; j < 4; j++)
+ {
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].clear();
+ mRT->shadow[j].flush();
+ }
+ }*/
+
+ //for (S32 j = 0; j < (gCubeSnapshot ? 1 : 4); j++)
+ for (S32 j = 0; j < 4; j++)
{
if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
{
mShadowFrustPoints[j].clear();
}
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j);
//restore render matrices
set_current_modelview(saved_view);
@@ -10323,12 +10241,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadowCamera[j+4] = shadow_cam;
}
- mShadow[j].bindTarget();
+ mRT->shadow[j].bindTarget();
{
LLGLDepthTest depth(GL_TRUE);
- mShadow[j].clear();
+ mRT->shadow[j].clear();
}
- mShadow[j].flush();
+ mRT->shadow[j].flush();
mShadowError.mV[j] = 0.f;
mShadowFOV.mV[j] = 0.f;
@@ -10615,18 +10533,18 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
stop_glerror();
- mShadow[j].bindTarget();
- mShadow[j].getViewport(gGLViewport);
- mShadow[j].clear();
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].getViewport(gGLViewport);
+ mRT->shadow[j].clear();
- U32 target_width = mShadow[j].getWidth();
+ U32 target_width = mRT->shadow[j].getWidth();
{
static LLCullResult result[4];
renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width);
}
- mShadow[j].flush();
+ mRT->shadow[j].flush();
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
{
@@ -10641,142 +10559,150 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (gen_shadow)
{
- LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
- F32 fade_amt = gFrameIntervalSeconds.value()
- * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
+ if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
+ {
+ LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
+ F32 fade_amt = gFrameIntervalSeconds.value()
+ * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
- //update shadow targets
- for (U32 i = 0; i < 2; i++)
- { //for each current shadow
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);
+ //update shadow targets
+ for (U32 i = 0; i < 2; i++)
+ { //for each current shadow
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i);
+
+ if (mShadowSpotLight[i].notNull() &&
+ (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
+ mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
+ { //keep this spotlight
+ mSpotLightFade[i] = llmin(mSpotLightFade[i] + fade_amt, 1.f);
+ }
+ else
+ { //fade out this light
+ mSpotLightFade[i] = llmax(mSpotLightFade[i] - fade_amt, 0.f);
- if (mShadowSpotLight[i].notNull() &&
- (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
- mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
- { //keep this spotlight
- mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
- }
- else
- { //fade out this light
- mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
-
- if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
- { //faded out, grab one of the pending spots (whichever one isn't already taken)
- if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[0];
- }
- else
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[1];
- }
- }
- }
- }
+ if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
+ { //faded out, grab one of the pending spots (whichever one isn't already taken)
+ if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i + 1) % 2])
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[0];
+ }
+ else
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[1];
+ }
+ }
+ }
+ }
+ }
- for (S32 i = 0; i < 2; i++)
- {
- set_current_modelview(saved_view);
- set_current_projection(saved_proj);
+ for (S32 i = 0; i < 2; i++)
+ {
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
- if (mShadowSpotLight[i].isNull())
- {
- continue;
- }
+ if (mShadowSpotLight[i].isNull())
+ {
+ continue;
+ }
- LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
+ LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
- if (!volume)
- {
- mShadowSpotLight[i] = NULL;
- continue;
- }
+ if (!volume)
+ {
+ mShadowSpotLight[i] = NULL;
+ continue;
+ }
- LLDrawable* drawable = mShadowSpotLight[i];
+ LLDrawable* drawable = mShadowSpotLight[i];
- LLVector3 params = volume->getSpotLightParams();
- F32 fov = params.mV[0];
+ LLVector3 params = volume->getSpotLightParams();
+ F32 fov = params.mV[0];
- //get agent->light space matrix (modelview)
- LLVector3 center = drawable->getPositionAgent();
- LLQuaternion quat = volume->getRenderRotation();
+ //get agent->light space matrix (modelview)
+ LLVector3 center = drawable->getPositionAgent();
+ LLQuaternion quat = volume->getRenderRotation();
- //get near clip plane
- LLVector3 scale = volume->getScale();
- LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
- at_axis *= quat;
+ //get near clip plane
+ LLVector3 scale = volume->getScale();
+ LLVector3 at_axis(0, 0, -scale.mV[2] * 0.5f);
+ at_axis *= quat;
- LLVector3 np = center+at_axis;
- at_axis.normVec();
+ LLVector3 np = center + at_axis;
+ at_axis.normVec();
- //get origin that has given fov for plane np, at_axis, and given scale
- F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
+ //get origin that has given fov for plane np, at_axis, and given scale
+ F32 dist = (scale.mV[1] * 0.5f) / tanf(fov * 0.5f);
- LLVector3 origin = np - at_axis*dist;
+ LLVector3 origin = np - at_axis * dist;
- LLMatrix4 mat(quat, LLVector4(origin, 1.f));
+ LLMatrix4 mat(quat, LLVector4(origin, 1.f));
- view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
+ view[i + 4] = glh::matrix4f((F32*)mat.mMatrix);
- view[i+4] = view[i+4].inverse();
+ view[i + 4] = view[i + 4].inverse();
- //get perspective matrix
- F32 near_clip = dist+0.01f;
- F32 width = scale.mV[VX];
- F32 height = scale.mV[VY];
- F32 far_clip = dist+volume->getLightRadius()*1.5f;
+ //get perspective matrix
+ F32 near_clip = dist + 0.01f;
+ F32 width = scale.mV[VX];
+ F32 height = scale.mV[VY];
+ F32 far_clip = dist + volume->getLightRadius() * 1.5f;
- F32 fovy = fov * RAD_TO_DEG;
- F32 aspect = width/height;
-
- proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
+ F32 fovy = fov * RAD_TO_DEG;
+ F32 aspect = width / height;
- //translate and scale to from [-1, 1] to [0, 1]
- glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
- 0.f, 0.5f, 0.f, 0.5f,
- 0.f, 0.f, 0.5f, 0.5f,
- 0.f, 0.f, 0.f, 1.f);
+ proj[i + 4] = gl_perspective(fovy, aspect, near_clip, far_clip);
- set_current_modelview(view[i+4]);
- set_current_projection(proj[i+4]);
+ //translate and scale to from [-1, 1] to [0, 1]
+ glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+ 0.f, 0.5f, 0.f, 0.5f,
+ 0.f, 0.f, 0.5f, 0.5f,
+ 0.f, 0.f, 0.f, 1.f);
- mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
-
- for (U32 j = 0; j < 16; j++)
- {
- gGLLastModelView[j] = mShadowModelview[i+4].m[j];
- gGLLastProjection[j] = mShadowProjection[i+4].m[j];
- }
+ set_current_modelview(view[i + 4]);
+ set_current_projection(proj[i + 4]);
- mShadowModelview[i+4] = view[i+4];
- mShadowProjection[i+4] = proj[i+4];
+ mSunShadowMatrix[i + 4] = trans * proj[i + 4] * view[i + 4] * inv_view;
- LLCamera shadow_cam = camera;
- shadow_cam.setFar(far_clip);
- shadow_cam.setOrigin(origin);
+ for (U32 j = 0; j < 16; j++)
+ {
+ gGLLastModelView[j] = mShadowModelview[i + 4].m[j];
+ gGLLastProjection[j] = mShadowProjection[i + 4].m[j];
+ }
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+ mShadowModelview[i + 4] = view[i + 4];
+ mShadowProjection[i + 4] = proj[i + 4];
- stop_glerror();
+ if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
+ {
+ LLCamera shadow_cam = camera;
+ shadow_cam.setFar(far_clip);
+ shadow_cam.setOrigin(origin);
- mShadow[i+4].bindTarget();
- mShadow[i+4].getViewport(gGLViewport);
- mShadow[i+4].clear();
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- U32 target_width = mShadow[i+4].getWidth();
+ stop_glerror();
+
+ //
+
+ mSpotShadow[i].bindTarget();
+ mSpotShadow[i].getViewport(gGLViewport);
+ mSpotShadow[i].clear();
+
+ U32 target_width = mSpotShadow[i].getWidth();
- static LLCullResult result[2];
+ static LLCullResult result[2];
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i);
- RenderSpotLight = drawable;
+ RenderSpotLight = drawable;
- renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
+ renderShadow(view[i + 4], proj[i + 4], shadow_cam, result[i], FALSE, FALSE, target_width);
- RenderSpotLight = nullptr;
+ RenderSpotLight = nullptr;
- mShadow[i+4].flush();
- }
+ mSpotShadow[i].flush();
+ }
+ }
}
else
{ //no spotlight shadows
@@ -10849,6 +10775,7 @@ static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor");
void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
{
LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR);
+ LL_PROFILE_GPU_ZONE("generateImpostor");
LLGLState::checkStates();
LLGLState::checkTextureChannels();
@@ -10919,22 +10846,47 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
{
markVisible(avatar->mDrawable, *viewer_camera);
- LLVOAvatar::attachment_map_t::iterator iter;
- for (iter = avatar->mAttachmentPoints.begin();
- iter != avatar->mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment *attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- if (LLViewerObject* attached_object = attachment_iter->get())
- {
- markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
- }
- }
- }
+ if (preview_avatar)
+ {
+ // Only show rigged attachments for preview
+ LLVOAvatar::attachment_map_t::iterator iter;
+ for (iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment *attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && attached_object->isRiggedMesh())
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
+ }
+ }
+ }
+ else
+ {
+ LLVOAvatar::attachment_map_t::iterator iter;
+ for (iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment *attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
+ }
+ }
+ }
}
stateSort(*LLViewerCamera::getInstance(), result);
@@ -11092,8 +11044,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
- LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF );
- glDrawBuffersARB(1, &buff);
+ glDrawBuffers(1, &buff);
}
LLGLDisable blend(GL_BLEND);
@@ -11493,3 +11444,9 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
+void LLPipeline::overrideEnvironmentMap()
+{
+ //mReflectionMapManager.mProbes.clear();
+ //mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin());
+}
+
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 62d3ae7a39..59858cfcfc 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -38,6 +38,7 @@
#include "llgl.h"
#include "lldrawable.h"
#include "llrendertarget.h"
+#include "llreflectionmapmanager.h"
#include <stack>
@@ -50,6 +51,7 @@ class LLVOAvatar;
class LLVOPartGroup;
class LLGLSLShader;
class LLDrawPoolAlpha;
+class LLSettingsSky;
typedef enum e_avatar_skinning_method
{
@@ -187,6 +189,7 @@ public:
LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
bool pick_transparent,
bool pick_rigged,
+ bool pick_unselectable,
S32* face_hit, // return the face hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -216,8 +219,9 @@ public:
U32 addObject(LLViewerObject *obj);
void enableShadows(const bool enable_shadows);
- void releaseShadowTargets();
- void releaseShadowTarget(U32 index);
+ void releaseSpotShadowTargets();
+ void releaseSunShadowTargets();
+ void releaseSunShadowTarget(U32 index);
// void setLocalLighting(const bool local_lighting);
// bool isLocalLightingEnabled() const;
@@ -286,19 +290,28 @@ public:
void renderGeom(LLCamera& camera, bool forceVBOUpdate = false);
- void renderGeomDeferred(LLCamera& camera);
- void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
+ void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false);
+ void renderGeomPostDeferred(LLCamera& camera);
void renderGeomShadow(LLCamera& camera);
void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
void unbindDeferredShader(LLGLSLShader& shader);
- void renderDeferredLighting(LLRenderTarget* light_target);
+
+ // set env_mat parameter in given shader
+ void setEnvMat(LLGLSLShader& shader);
+
+ void bindReflectionProbes(LLGLSLShader& shader);
+ void unbindReflectionProbes(LLGLSLShader& shader);
+
+
+
+ void renderDeferredLighting();
void postDeferredGammaCorrect(LLRenderTarget* screen_target);
- void generateWaterReflection(LLCamera& camera);
void generateSunShadow(LLCamera& camera);
- LLRenderTarget* getShadowTarget(U32 i);
+ LLRenderTarget* getSunShadowTarget(U32 i);
+ LLRenderTarget* getSpotShadowTarget(U32 i);
void generateHighlight(LLCamera& camera);
void renderHighlight(const LLViewerObject* obj, F32 fade);
@@ -426,6 +439,9 @@ public:
void hideObject( const LLUUID& id );
void restoreHiddenObject( const LLUUID& id );
+ LLReflectionMapManager mReflectionMapManager;
+ void overrideEnvironmentMap();
+
private:
void unloadShaders();
void addToQuickLookup( LLDrawPool* new_poolp );
@@ -460,6 +476,8 @@ public:
RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
+ RENDER_TYPE_ALPHA_PRE_WATER = LLDrawPool::POOL_ALPHA_PRE_WATER,
+ RENDER_TYPE_ALPHA_POST_WATER = LLDrawPool::POOL_ALPHA_POST_WATER,
RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE,
RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED,
@@ -517,6 +535,8 @@ public:
RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED,
+ RENDER_TYPE_PASS_PBR_OPAQUE = LLRenderPass::PASS_PBR_OPAQUE,
+ RENDER_TYPE_PASS_PBR_OPAQUE_RIGGED = LLRenderPass::PASS_PBR_OPAQUE_RIGGED,
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
RENDER_TYPE_VOLUME,
@@ -574,7 +594,8 @@ public:
RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used
RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,
- RENDER_DEBUG_IMPOSTORS = 0x100000000
+ RENDER_DEBUG_IMPOSTORS = 0x100000000,
+ RENDER_DEBUG_REFLECTION_PROBES = 0x200000000
};
public:
@@ -612,7 +633,6 @@ public:
static bool sUseTriStrips;
static bool sUseFarClip;
static bool sShadowRender;
- static bool sWaterReflections;
static bool sDynamicLOD;
static bool sPickAvatar;
static bool sReflectionRender;
@@ -626,26 +646,50 @@ public:
static bool sRenderAttachedLights;
static bool sRenderAttachedParticles;
static bool sRenderDeferred;
+ static bool sReflectionProbesEnabled;
+ static bool sRenderPBR;
static S32 sVisibleLightCount;
static bool sRenderingHUDs;
static F32 sDistortionWaterClipPlaneMargin;
static LLTrace::EventStatHandle<S64> sStatBatchSize;
- //screen texture
- U32 mScreenWidth;
- U32 mScreenHeight;
-
- LLRenderTarget mScreen;
- LLRenderTarget mUIScreen;
- LLRenderTarget mDeferredScreen;
- LLRenderTarget mFXAABuffer;
- LLRenderTarget mEdgeMap;
- LLRenderTarget mDeferredDepth;
- LLRenderTarget mOcclusionDepth;
- LLRenderTarget mDeferredLight;
- LLRenderTarget mHighlight;
- LLRenderTarget mPhysicsDisplay;
+ class RenderTargetPack
+ {
+ public:
+ U32 width = 0;
+ U32 height = 0;
+
+ //screen texture
+ LLRenderTarget screen;
+ LLRenderTarget uiScreen;
+ LLRenderTarget deferredScreen;
+ LLRenderTarget fxaaBuffer;
+ LLRenderTarget edgeMap;
+ LLRenderTarget deferredDepth;
+ LLRenderTarget occlusionDepth;
+ LLRenderTarget deferredLight;
+
+ //sun shadow map
+ LLRenderTarget shadow[4];
+ LLRenderTarget shadowOcclusion[4];
+ };
+
+ // main full resoltuion render target
+ RenderTargetPack mMainRT;
+
+ // auxillary 512x512 render target pack
+ RenderTargetPack mAuxillaryRT;
+
+ // currently used render target pack
+ RenderTargetPack* mRT;
+
+ LLRenderTarget mSpotShadow[2];
+ LLRenderTarget mSpotShadowOcclusion[2];
+
+ LLRenderTarget mHighlight;
+ LLRenderTarget mPhysicsDisplay;
+ LLRenderTarget mPbrBrdfLut;
LLCullResult mSky;
LLCullResult mReflectedObjects;
@@ -657,15 +701,16 @@ public:
//utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
LLPointer<LLVertexBuffer> mCubeVB;
- //sun shadow map
- LLRenderTarget mShadow[6];
- LLRenderTarget mShadowOcclusion[6];
+ //list of currently bound reflection maps
+ std::vector<LLReflectionMap*> mReflectionMaps;
+
std::vector<LLVector3> mShadowFrustPoints[4];
LLVector4 mShadowError;
LLVector4 mShadowFOV;
LLVector3 mShadowFrustOrigin[4];
LLCamera mShadowCamera[8];
LLVector3 mShadowExtents[4][2];
+ // TODO : separate Sun Shadow and Spot Shadow matrices
glh::matrix4f mSunShadowMatrix[6];
glh::matrix4f mShadowModelview[6];
glh::matrix4f mShadowProjection[6];
@@ -845,21 +890,23 @@ protected:
// For quick-lookups into mPools (mapped by texture pointer)
std::map<uintptr_t, LLDrawPool*> mTerrainPools;
std::map<uintptr_t, LLDrawPool*> mTreePools;
- LLDrawPoolAlpha* mAlphaPool;
- LLDrawPool* mSkyPool;
- LLDrawPool* mTerrainPool;
- LLDrawPool* mWaterPool;
- LLDrawPool* mGroundPool;
- LLRenderPass* mSimplePool;
- LLRenderPass* mGrassPool;
- LLRenderPass* mAlphaMaskPool;
- LLRenderPass* mFullbrightAlphaMaskPool;
- LLRenderPass* mFullbrightPool;
- LLDrawPool* mInvisiblePool;
- LLDrawPool* mGlowPool;
- LLDrawPool* mBumpPool;
- LLDrawPool* mMaterialsPool;
- LLDrawPool* mWLSkyPool;
+ LLDrawPoolAlpha* mAlphaPoolPreWater = nullptr;
+ LLDrawPoolAlpha* mAlphaPoolPostWater = nullptr;
+ LLDrawPool* mSkyPool = nullptr;
+ LLDrawPool* mTerrainPool = nullptr;
+ LLDrawPool* mWaterPool = nullptr;
+ LLDrawPool* mGroundPool = nullptr;
+ LLRenderPass* mSimplePool = nullptr;
+ LLRenderPass* mGrassPool = nullptr;
+ LLRenderPass* mAlphaMaskPool = nullptr;
+ LLRenderPass* mFullbrightAlphaMaskPool = nullptr;
+ LLRenderPass* mFullbrightPool = nullptr;
+ LLDrawPool* mInvisiblePool = nullptr;
+ LLDrawPool* mGlowPool = nullptr;
+ LLDrawPool* mBumpPool = nullptr;
+ LLDrawPool* mMaterialsPool = nullptr;
+ LLDrawPool* mWLSkyPool = nullptr;
+ LLDrawPool* mPBROpaquePool = nullptr;
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
public:
@@ -966,7 +1013,6 @@ public:
static LLVector3 RenderShadowGaussian;
static F32 RenderShadowBlurDistFactor;
static bool RenderDeferredAtmospheric;
- static S32 RenderReflectionDetail;
static F32 RenderHighlightFadeTime;
static LLVector3 RenderShadowClipPlanes;
static LLVector3 RenderShadowOrthoClipPlanes;
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 7beb013fba..c3ce83e834 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -514,8 +514,8 @@
name="MapFrustumColor"
reference="White_10" />
<color
- name="MapFrustumRotatingColor"
- value="1 1 1 0.2" />
+ name="MapParcelOutlineColor"
+ value="1 1 0 0.5" />
<color
name="MapTrackColor"
reference="Red" />
@@ -607,10 +607,10 @@
value="0 0 0 1" />
<color
name="NetMapGroupOwnAboveWater"
- reference="Purple" />
+ value="0.85 0 0.85 1" />
<color
name="NetMapGroupOwnBelowWater"
- value="0.78 0 0.78 1" />
+ value="0.63 0 0.63 1" />
<color
name="NetMapOtherOwnAboveWater"
value="0.24 0.24 0.24 1" />
@@ -619,10 +619,10 @@
value="0.12 0.12 0.12 1" />
<color
name="NetMapYouOwnAboveWater"
- value="0 1 1 1" />
+ value="0 0.85 0.85 1" />
<color
name="NetMapYouOwnBelowWater"
- value="0 0.78 0.78 1" />
+ value="0 0.63 0.63 1" />
<color
name="NotifyBoxColor"
value="LtGray" />
@@ -886,6 +886,22 @@
name="PanelNotificationListItem"
value="0.3 0.3 0.3 .3" />
+ <!-- profiles -->
+ <color
+ name="StatusUserOnline"
+ reference="White" />
+ <color
+ name="StatusUserOffline"
+ reference="LtGray_35" />
+ <!-- Groups visible in own profiles -->
+ <color
+ name="GroupVisibleInProfile"
+ reference="TextBgFocusColor" />
+ <color
+ name="GroupHiddenInProfile"
+ reference="Gray" />
+
+
<!-- Generic color names (legacy) -->
<color
name="white"
diff --git a/indra/newview/skins/default/textures/default_irradiance.png b/indra/newview/skins/default/textures/default_irradiance.png
new file mode 100644
index 0000000000..899e0ddf2a
--- /dev/null
+++ b/indra/newview/skins/default/textures/default_irradiance.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png
new file mode 100644
index 0000000000..9a81c5f94b
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png
new file mode 100644
index 0000000000..88012cf8d1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png
new file mode 100644
index 0000000000..ab02e7d42d
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png
new file mode 100644
index 0000000000..63b4bd2127
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png
new file mode 100644
index 0000000000..4200182b0c
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png
new file mode 100644
index 0000000000..e12887f489
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/CopyBright.png b/indra/newview/skins/default/textures/icons/CopyBright.png
new file mode 100644
index 0000000000..8d21c47295
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/CopyBright.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Material.png b/indra/newview/skins/default/textures/icons/Inv_Material.png
new file mode 100644
index 0000000000..f5918ceaed
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_Material.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png
new file mode 100644
index 0000000000..aeba6b70f7
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png
new file mode 100644
index 0000000000..d668fd8dfa
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png
new file mode 100644
index 0000000000..8f8caa10d8
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png
new file mode 100644
index 0000000000..42a209dda5
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png
new file mode 100644
index 0000000000..644edf0ef6
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png
new file mode 100644
index 0000000000..629c05ecb8
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png
new file mode 100644
index 0000000000..ecf66c0ee1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png
new file mode 100644
index 0000000000..26123938fa
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
deleted file mode 100644
index 3bb7f7183c..0000000000
--- a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png
new file mode 100644
index 0000000000..3a2ed399b2
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png
new file mode 100644
index 0000000000..789f59a491
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png
new file mode 100644
index 0000000000..4fb56c389c
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png
new file mode 100644
index 0000000000..ae04a256a4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_ui_collapse_icon.png b/indra/newview/skins/default/textures/map_ui_collapse_icon.png
new file mode 100644
index 0000000000..e4de49d4af
--- /dev/null
+++ b/indra/newview/skins/default/textures/map_ui_collapse_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_ui_expand_icon.png b/indra/newview/skins/default/textures/map_ui_expand_icon.png
new file mode 100644
index 0000000000..08734b4cc0
--- /dev/null
+++ b/indra/newview/skins/default/textures/map_ui_expand_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a36b859b6c..5bf27bb64d 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -67,8 +67,6 @@ with the same filename but different name
<texture name="Audio_Off" file_name="icons/Audio_Off.png" preload="false" />
<texture name="Audio_Press" file_name="icons/Audio_Press.png" preload="false" />
- <texture name="Avaline_Icon" file_name="icons/avaline_default_icon.jpg" preload="true" />
-
<texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" />
<texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />
@@ -191,6 +189,7 @@ with the same filename but different name
<texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
<texture name="Copy" file_name="icons/Copy.png" preload="false" />
+ <texture name="CopyBright" file_name="icons/CopyBright.png" preload="false" />
<texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
@@ -303,6 +302,7 @@ with the same filename but different name
<texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" />
<texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" />
<texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" />
+ <texture name="Inv_Material" file_name="icons/Inv_Material.png" preload="false" />
<texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" />
<texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" />
<texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" />
@@ -447,6 +447,13 @@ with the same filename but different name
<texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" />
<texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Disabled" file_name="icons/ClipboardSmallMenu_Disabled.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Off" file_name="icons/ClipboardSmallMenu_Off.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Press" file_name="icons/ClipboardSmallMenu_Press.png" preload="false" />
+ <texture name="ClipboardMenu_Disabled" file_name="icons/ClipboardMenu_Disabled.png" preload="false" />
+ <texture name="ClipboardMenu_Off" file_name="icons/ClipboardMenu_Off.png" preload="false" />
+ <texture name="ClipboardMenu_Press" file_name="icons/ClipboardMenu_Press.png" preload="false" />
+
<texture name="OutboxStatus_Success" file_name="green_checkmark.png" preload="false" />
<texture name="OutboxStatus_Warning" file_name="icons/pop_up_caution.png" preload="false" />
<texture name="OutboxStatus_Error" file_name="red_x.png" preload="false" />
@@ -505,6 +512,19 @@ with the same filename but different name
<texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
+ <texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_On_Pressed" file_name="icons/profile_group_visibility_eye_on_pressed.png" preload="true"/>
+ <texture name="Profile_Friend_Offline" file_name="icons/Profile_Friend_Offline.png" preload="true"/>
+ <texture name="Profile_Friend_Online" file_name="icons/Profile_Friend_Online.png" preload="true"/>
+ <texture name="Profile_Perm_Find_Disabled" file_name="icons/Profile_Perm_Find_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Find_Enabled" file_name="icons/Profile_Perm_Find_Enabled.png" preload="true"/>
+ <texture name="Profile_Perm_Objects_Disabled" file_name="icons/Profile_Perm_Objects_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/>
+ <texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/>
+
<texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
<texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
<texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
@@ -612,8 +632,7 @@ with the same filename but different name
<texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" />
<texture name="login_sl_logo_small" file_name="windows/login_sl_logo_small.png" preload="true" />
- <texture name="first_login_image_left" file_name="windows/first_login_image_left.png" preload="true" />
- <texture name="first_login_image_right" file_name="windows/first_login_image_right.png" preload="true" />
+ <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" />
<texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" />
<texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" />
@@ -804,6 +823,8 @@ with the same filename but different name
<texture name="map_infohub.tga" />
<texture name="map_telehub.tga" />
<texture name="map_track_16.tga" />
+ <texture name="map_ui_collapse_icon.png" />
+ <texture name="map_ui_expand_icon.png" />
<texture name="notify_caution_icon.tga" />
diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg
new file mode 100644
index 0000000000..30f31341ed
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/first_login_image.jpg
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png
deleted file mode 100644
index 77904d7d12..0000000000
--- a/indra/newview/skins/default/textures/windows/first_login_image_left.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png
deleted file mode 100644
index 35ecce9c07..0000000000
--- a/indra/newview/skins/default/textures/windows/first_login_image_right.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/xui/da/panel_me.xml b/indra/newview/skins/default/xui/da/panel_me.xml
deleted file mode 100644
index f98ced5f91..0000000000
--- a/indra/newview/skins/default/xui/da/panel_me.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Min profil" name="panel_me">
- <tab_container name="tabs">
- <panel label="MIN PROFIL" name="panel_profile"/>
- <panel label="MINE FAVORITTER" name="panel_picks"/>
- </tab_container>
-</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml
index 45946fd222..c8a3ad328e 100644
--- a/indra/newview/skins/default/xui/da/panel_region_texture.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml
@@ -7,8 +7,8 @@
ukendt
</text>
<text name="detail_texture_text">
- Terræn teksturer (kræver 512x512, 24 bit .tga filer)
- </text>
+ Terræn teksturer (kræver 1024x1024, 24 bit .tga filer)
+ </text>
<text name="height_text_lbl">
1 (Lav)
</text>
diff --git a/indra/newview/skins/default/xui/da/panel_side_tray.xml b/indra/newview/skins/default/xui/da/panel_side_tray.xml
deleted file mode 100644
index 66c3e69904..0000000000
--- a/indra/newview/skins/default/xui/da/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Åbn/luk sidebar" name="sidebar_openclose" tab_title="Åbn/luk sidebar"/>
- <sidetray_tab description="Hjem." name="sidebar_home" tab_title="Hjem">
- <panel label="hjem" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Redigér din profile og favoritter." name="sidebar_me" tab_title="Min profil">
- <panel_container name="panel_container">
- <panel label="Mig" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find venner, kontakter og personer tæt på." name="sidebar_people" tab_title="Personer">
- <panel_container name="panel_container">
- <panel label="Gruppe profil" name="panel_group_info_sidetray"/>
- <panel label="Blokerede beboere og objekter" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find steder du vil hen og steder du har været før." label="Steder" name="sidebar_places" tab_title="Steder">
- <panel label="Steder" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Browse din beholdning." name="sidebar_inventory" tab_title="Min beholdning">
- <panel label="Redigér beholdning" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Ændre dit nuværende udseende" name="sidebar_appearance" tab_title="Mit udseende">
- <panel label="Redigér udseende" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 814305c1bc..e4f99d14e9 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -106,7 +106,7 @@
<string name="LoginFailedNoNetwork">
Netværksfejl: Kunne ikke etablere forbindelse, check venligst din netværksforbindelse.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Login fejlede.
</string>
<string name="Quit">
@@ -443,9 +443,6 @@ Prøv venligst om lidt igen.
<string name="GroupNameNone">
(ingen)
</string>
- <string name="AvalineCaller">
- Avaline opkalder [ORDER]
- </string>
<string name="AssetErrorNone">
Ingen fejl
</string>
diff --git a/indra/newview/skins/default/xui/de/floater_preview_texture.xml b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
index eacd11c3e6..b386d0288c 100644
--- a/indra/newview/skins/default/xui/de/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
In Inventar kopieren
</floater.string>
- <text name="desc txt">
- Beschreibung:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Vorschau Seitenverhältnis
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen">
- <combo_item name="Unconstrained">
- keines
- </combo_item>
- <combo_item name="1:1" tool_tip="Gruppeninsignien oder Beschreibung">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE]-Profil">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Anzeigen und Suchergebnisse, Landmarken">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Über Land">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Profilauswahl">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Verwerfen" name="Discard"/>
- <button label="Speichern unter" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Beschreibung:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Vorschau Seitenverhältnis
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Verwerfen" name="Discard"/>
+ <button label="Speichern unter" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_profile.xml b/indra/newview/skins/default/xui/de/floater_profile.xml
new file mode 100644
index 0000000000..eb03463930
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interessen" name="panel_profile_interests"/>
+ <panel label="Auswahlen" name="panel_profile_picks"/>
+ <panel label="Anzeige" name="panel_profile_classifieds"/>
+ <panel label="Echtes Leben" name="panel_profile_firstlife"/>
+ <panel label="Hinweise" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Profiländerungen speichern und schließen"/>
+ <button label="Abbrechen" label_selected="Abbrechen" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml
index f0152ad8cd..636f320a95 100644
--- a/indra/newview/skins/default/xui/de/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
E-Mail senden
</string>
+ <string name="facebook_progress_str">
+ Auf Facebook posten
+ </string>
<string name="profile_progress_str">
Posten
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Speichern auf Computer
</string>
+ <string name="facebook_succeeded_str">
+ Bild hochgeladen
+ </string>
<string name="profile_succeeded_str">
Bild hochgeladen
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Auf Computer gespeichert!
</string>
+ <string name="facebook_failed_str">
+ Fehler beim Hochladen des Bilds in Ihre Facebook-Chronik.
+ </string>
<string name="profile_failed_str">
Fehler beim Hochladen des Bilds in Ihr Profil.
</string>
diff --git a/indra/newview/skins/default/xui/de/menu_name_field.xml b/indra/newview/skins/default/xui/de/menu_name_field.xml
new file mode 100644
index 0000000000..1d293c9361
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Anzeigenamen kopieren" name="copy_display"/>
+ <menu_item_call label="Agent-Namen kopieren" name="copy_name"/>
+ <menu_item_call label="Agent-ID kopieren" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 359a835630..a72784f70b 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -2698,6 +2698,9 @@ Wählen Sie eine kleinere Landfläche.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_classified.xml b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
index bd270697ea..8adacb4a5f 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Abbrechen" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
index f6a8fda23e..1a0bbc7d30 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die gleichzeitig Einwohner von Second Life sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/>
- <string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, gehen Sie zur Registerkarte „Status“."/>
+ <string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die ebenfalls Second Life-Einwohner sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/>
+ <string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, wechseln Sie zur Registerkarte &quot;Status&quot;."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="SL-Freunde"/>
<accordion_tab name="tab_suggested_friends" title="Diese Personen als SL-Freunde hinzufügen"/>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
index bc48931129..fac9fe9984 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
@@ -2,10 +2,10 @@
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Bildauflösung">
<combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1200x630" name="1200x630"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
<combo_box name="filters_combobox" tool_tip="Bildfilter">
<combo_box.item label="Kein Filter" name="NoFilter"/>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_status.xml b/indra/newview/skins/default/xui/de/panel_facebook_status.xml
index 23c9d3b75f..1fefef548e 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_status.xml
@@ -13,7 +13,7 @@
</text>
</panel>
<text name="status_caption_label">
- Was machst du gerade?
+ Was machen Sie gerade?
</text>
<button label="Posten" name="post_status_btn"/>
<button label="Abbrechen" name="cancel_status_btn"/>
diff --git a/indra/newview/skins/default/xui/de/panel_group_general.xml b/indra/newview/skins/default/xui/de/panel_group_general.xml
index 9fec5a242d..e50124c37e 100644
--- a/indra/newview/skins/default/xui/de/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_general.xml
@@ -46,7 +46,7 @@ Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen.
<check_box label="Jeder kann beitreten" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/>
<check_box label="Kosten für Beitritt" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen"/>
<spinner label="L$" name="spin_enrollment_fee" tool_tip="Wenn Beitrittsgebühr aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/>
- <combo_box name="group_mature_check" tool_tip="Inhaltseinstufungen kennzeichnen die in einer Gruppe zulässigen Inhalte und Verhaltensweisen">
+ <combo_box name="group_mature_check" tool_tip="Legt fest, ob Ihre Gruppe als moderat eingestufte Informationen enthält">
<combo_item name="select_mature">
- Inhaltseinstufung auswählen -
</combo_item>
diff --git a/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..fc911a64df
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Unbekannt"/>
+ <button name="info_btn" tool_tip="Mehr Infos"/>
+ <button name="profile_btn" tool_tip="Profil anzeigen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_me.xml b/indra/newview/skins/default/xui/de/panel_me.xml
deleted file mode 100644
index f49446fbbf..0000000000
--- a/indra/newview/skins/default/xui/de/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mein Profil" name="panel_me">
- <panel label="MEINE AUSWAHLEN" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml
index 81de679429..e4a4c1033e 100644
--- a/indra/newview/skins/default/xui/de/panel_people.xml
+++ b/indra/newview/skins/default/xui/de/panel_people.xml
@@ -40,6 +40,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Alle"/>
+ <accordion_tab name="tab_suggested_friends" title="Potenzielle Freunde"/>
</accordion>
</panel>
<panel label="GRUPPEN" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_profile_classified.xml b/indra/newview/skins/default/xui/de/panel_profile_classified.xml
new file mode 100644
index 0000000000..5c11a01977
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderat
+ </panel.string>
+ <panel.string name="type_pg">
+ Generelle Inhalte
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] Teleportieren, [MAP] Karten, [PROFILE] Profil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Aktiviert
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Deaktiviert
+ </panel.string>
+ <panel.string name="location_notice">
+ (wird nach dem Speichern aktualisiert)
+ </panel.string>
+ <string name="publish_label">
+ Veröffentlichen
+ </string>
+ <string name="save_label">
+ Speichern
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Standort:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Inhaltsart:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Kategorie:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Erstellungsdatum:"/>
+ <text_editor name="creation_date" tool_tip="Erstellungsdatum" value="[date]"/>
+ <text name="price_for_listing_label" value="Preis für Auflistung:"/>
+ <text_editor name="price_for_listing" tool_tip="Preis für Auflistung.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Klicks:"/>
+ <text_editor name="click_through_text" tool_tip="Click-Through-Daten" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Autom. erneuern:"/>
+ <text name="auto_renew" value="Aktiviert"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Beschreibung:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titel:
+ </text>
+ <text name="description_label">
+ Beschreibung:
+ </text>
+ <text name="location_label">
+ Standort:
+ </text>
+ <text name="classified_location_edit">
+ Laden...
+ </text>
+ <button label="Aktuellen Standort verwenden" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Kategorie:"/>
+ <text name="content_type_label" value="Inhaltsart:"/>
+ <icons_combo_box label="Generelle Inhalte" name="content_type_edit">
+ <icons_combo_box.item label="Moderate Inhalte" name="mature_ci" value="Adult"/>
+ <icons_combo_box.item label="Generelle Inhalte" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Jede Woche automatisch erneuern" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Preis für Auflistung:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Preis für Auflistung." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teleportieren" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Karte" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Bearbeiten" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Abbrechen" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..83549cb138
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anzeige" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Keine Anzeigen"/>
+ <button label="Neu..." name="new_btn"/>
+ <button label="Löschen..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Laden...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/floater_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml
index 2521920e83..0f65090209 100644
--- a/indra/newview/skins/default/xui/de/floater_picks.xml
+++ b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Auswahlen"/>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_interests.xml b/indra/newview/skins/default/xui/de/panel_profile_interests.xml
new file mode 100644
index 0000000000..0f36f76aa0
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interessen" name="panel_profile_interests">
+ <text name="I Want To:">
+ Ich möchte:
+ </text>
+ <check_box label="Erstellen" name="chk0"/>
+ <check_box label="Erkunden" name="chk1"/>
+ <check_box label="Treffen" name="chk2"/>
+ <check_box label="Angestellt werden" name="chk6"/>
+ <check_box label="Gruppe" name="chk3"/>
+ <check_box label="Kaufen" name="chk4"/>
+ <check_box label="Verkaufen" name="chk5"/>
+ <check_box label="Anstellen" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (wird geladen...)
+ </line_editor>
+ <text name="Skills:">
+ Fähigkeiten:
+ </text>
+ <check_box label="Texturen" name="schk0"/>
+ <check_box label="Architektur" name="schk1"/>
+ <check_box label="Modellierung" name="schk3"/>
+ <check_box label="Eventplanung" name="schk2"/>
+ <check_box label="Scripting" name="schk4"/>
+ <check_box label="Benutzerdefinierte Charaktere" name="schk5"/>
+ <line_editor name="skills_edit">
+ (wird geladen...)
+ </line_editor>
+ <text name="Languages:">
+ Sprachen:
+ </text>
+ <line_editor name="languages_edit">
+ (wird geladen...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_notes.xml b/indra/newview/skins/default/xui/de/panel_profile_notes.xml
new file mode 100644
index 0000000000..05c46ff858
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anmerkungen &amp; Privatsphäre" name="panel_notes">
+ <text name="status_message" value="Private Anmerkungen zu diesem Avatar:"/>
+ <text name="status_message2" value="Dieser Avatar darf:"/>
+ <check_box label="Sehen, wenn ich online bin" name="status_check"/>
+ <check_box label="Mich auf der Weltkarte sehen" name="map_check"/>
+ <check_box label="Meine Objekte bearbeiten, löschen oder nehmen" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_pick.xml b/indra/newview/skins/default/xui/de/panel_profile_pick.xml
new file mode 100644
index 0000000000..1f44ba8b1b
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (wird nach dem Speichern aktualisiert)
+ </panel.string>
+ <line_editor name="pick_location">
+ Laden...
+ </line_editor>
+ <button label="Teleportieren" name="teleport_btn"/>
+ <button label="Auf Karte anzeigen" name="show_on_map_btn"/>
+ <button label="Standort festlegen" name="set_to_curr_location_btn" tool_tip="Aktuellen Standort verwenden"/>
+ <button label="Auswahl speichern" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_picks.xml
new file mode 100644
index 0000000000..96403715e4
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Auswahlen" name="panel_picks">
+ <string name="no_picks" value="Keine Auswahl"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Erzählen Sie von Ihren Lieblingsorten in Second Life.
+ </text>
+ <button label="Neu..." name="new_btn"/>
+ <button label="Löschen..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Laden...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..baaa58e1d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Zurzeit online
+ </string>
+ <string name="status_offline">
+ Zurzeit offline
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=de
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=de
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Keine"/>
+ <string name="no_group_text" value="Keine"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Entwickler"/>
+ <string name="FSSupp" value="Support"/>
+ <string name="FSQualityAssurance" value="Fehlersuche"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Name:"/>
+ <button label="Name:" name="set_name" tool_tip="Anzeigenamen festlegen"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(wird geladen...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status unbekannt"/>
+ <text name="label" value="Second Life-Geburtsdatum:"/>
+ <text name="label2" value="Konto:"/>
+ <text name="partner_label" value="Partner:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruppen:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="In Gruppe einladen"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Info:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Objekt geben:"/>
+ <text name="Give inventory" tool_tip="Legen Sie hier Inventarobjekte ab, um Sie dieser Person zu geben.">
+ Inventarobjekt hier ablegen.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Auf Karte anzeigen" label_selected="Auf Karte anzeigen" name="show_on_map_btn" tool_tip="Einwohner auf Karte lokalisieren"/>
+ <button label="Bezahlen" label_selected="Bezahlen" name="pay" tool_tip="Geld an den Einwohner zahlen"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Teleportation anbieten" label_selected="Teleportation anbieten" name="teleport" tool_tip="Dem Einwohner eine Teleportation anbieten"/>
+ <button label="Instant Message" label_selected="Instant Message" name="im" tool_tip="Instant Message-Sitzung öffnen"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Freund hinzufügen" label_selected="Freund hinzufügen" name="add_friend" tool_tip="Dem Einwohner die Freundschaft anbieten"/>
+ <button label="Blockieren" name="block" tool_tip="Diesen Einwohner blockieren"/>
+ <button label="Blockierung aufheben" name="unblock" tool_tip="Diesen Einwohner nicht mehr blockieren"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="In Suche anzeigen" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_web.xml b/indra/newview/skins/default/xui/de/panel_profile_web.xml
new file mode 100644
index 0000000000..a03918f4b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Ladezeit: [TIME] Sekunden"/>
+ <line_editor name="url_edit">
+ (wird geladen..)
+ </line_editor>
+ <flyout_button label="Laden" name="load" tool_tip="Lädt diese Profilseite im integrierten Webbrowser.">
+ <flyout_button.item label="Im Viewer-Browser öffnen" name="open_item"/>
+ <flyout_button.item label="In externem Browser öffnen" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Webprofil ausklappen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
index 7801be30e4..42ba5b5269 100644
--- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Obere Terraingrenze" name="terrain_raise_spin"/>
<spinner label="Untere Terraingrenze" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 512x512)
- </text>
+ Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 1024x1024)
+ </text>
<text name="height_text_lbl">
1 (niedrig)
</text>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index ba26f721fe..0120f7e5bd 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -186,7 +186,7 @@ Voice-Server-Version: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Netzwerkfehler: Verbindung konnte nicht hergestellt werden. Bitte überprüfen Sie Ihre Netzwerkverbindung.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Anmeldung fehlgeschlagen
</string>
<string name="Quit">
@@ -356,6 +356,24 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="TestingDisconnect">
Verbindungsabbruch wird getestet
</string>
+ <string name="SocialFacebookConnecting">
+ Mit Facebook verbinden...
+ </string>
+ <string name="SocialFacebookPosting">
+ Posten...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook-Verbindung trennen...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problem beim Verbinden mit Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problem beim Posten auf Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problem beim Trennen der Facebook-Verbindung
+ </string>
<string name="SocialFlickrConnecting">
Verbinden mit Flickr...
</string>
@@ -673,9 +691,6 @@ nächsten Eigentümer angehängt werden.
<string name="GroupNameNone">
(keiner)
</string>
- <string name="AvalineCaller">
- Avaline-Anfrufer [ORDER]
- </string>
<string name="AssetErrorNone">
Kein Fehler
</string>
@@ -2578,9 +2593,21 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
<string name="NoPicksClassifiedsText">
Sie haben keine Auswahl oder Anzeigen erstelllt. Klicken Sie auf die „Plus&quot;-Schaltfläche, um eine Auswahl oder Anzeige zu erstellen.
</string>
+ <string name="NoPicksText">
+ Sie haben keine Auswahl erstellt. Klicken Sie auf die Schaltfläche &quot;Neu&quot;, um eine Auswahl zu erstellen.
+ </string>
+ <string name="NoClassifiedsText">
+ Sie haben keine Anzeigen erstellt. Klicken Sie auf die Schaltfläche &quot;Neu&quot;, um eine Anzeige zu erstellen.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
Der Einwohner hat keine Auswahl oder Anzeigen
</string>
+ <string name="NoAvatarPicksText">
+ Der Einwohner hat keine Auswahl
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Der Einwohner hat keine Anzeigen
+ </string>
<string name="PicksClassifiedsLoadingText">
Wird geladen...
</string>
@@ -4558,6 +4585,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="share_alert">
Objekte aus dem Inventar hier her ziehen
</string>
+ <string name="facebook_post_success">
+ Sie haben auf Facebook gepostet.
+ </string>
<string name="flickr_post_success">
Sie haben auf Flickr gepostet.
</string>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index b2d9e53039..4678d65b85 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -164,6 +164,7 @@
left_pad="2"
name="Description"
spellcheck="true"
+ parse_urls="true"
top_delta="0"
width="365"
word_wrap="true" />
@@ -1892,7 +1893,29 @@ Only large parcels can be listed in search.
left="110"
name="parcel_enable_voice_channel_local"
width="300" />
- </panel>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="media"
+ top_pad="10"
+ width="100">
+ Media:
+ </text>
+ <check_box
+ height="16"
+ label="Obscure MOAP"
+ layout="topleft"
+ left="110"
+ left_pad="0"
+ name="obscure_moap"
+ tool_tip="Media on a prim located outside the parcel should not play automatically for an agent within this parcel and vice versa."
+ width="300" />
+ </panel>
<panel
border="true"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml
index 38428b36fc..7278e55d57 100644
--- a/indra/newview/skins/default/xui/en/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/en/floater_build_options.xml
@@ -46,14 +46,14 @@
name="GridSubUnit"
top_pad="0"
width="200" />
- <check_box
+ <!-- <check_box
control_name="GridCrossSections"
height="16"
label="View cross-sections"
layout="topleft"
name="GridCrossSection"
top_pad="5"
- width="200" />
+ width="200" />-->
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_classified.xml
index 984894b016..5b14c827d0 100644
--- a/indra/newview/skins/default/xui/en/floater_picks.xml
+++ b/indra/newview/skins/default/xui/en/floater_classified.xml
@@ -2,20 +2,19 @@
<floater
positioning="cascading"
can_close="true"
- can_resize="true"
+ can_resize="false"
height="572"
help_topic="sidebar_me"
min_width="333"
min_height="440"
- name="floater_picks"
+ name="floater_classified"
save_rect="true"
- save_visibility="true"
- reuse_instance="true"
- title="Picks"
+ save_visibility="false"
+ title="Classified"
width="333" >
<panel
- class="panel_me"
+ class="panel_classified_info"
name="main_panel"
- filename="panel_me.xml"
+ filename="panel_classified_info.xml"
follows="all"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml b/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml
new file mode 100644
index 0000000000..63eaffde18
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<floater
+ legacy_header_height="18"
+ height="130"
+ min_height="130"
+ width="270"
+ min_width="270"
+ layout="topleft"
+ name="floater_combo"
+ title="floater_combo"
+ help_topic="floater_combo"
+ can_resize="false"
+ can_minimize="false">
+ <text
+ follows="top|left|right"
+ height="10"
+ layout="topleft"
+ left="20"
+ name="combo_text"
+ top="30"
+ width="200">
+ Select an option:
+ </text>
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ left="20"
+ name="combo_options"
+ top_delta="20"
+ width="230"/>
+ <button
+ follows="top|left"
+ height="23"
+ label="OK"
+ layout="topleft"
+ top_delta="40"
+ left="20"
+ name="combo_ok"
+ width="90"/>
+ <button
+ follows="top|left"
+ height="23"
+ label="Cancel"
+ layout="topleft"
+ left_pad="50"
+ name="combo_cancel"
+ width="90"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
index bba30626b2..632daaec7e 100644
--- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml
+++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
@@ -88,6 +88,7 @@
spellcheck="true"
text_readonly_color="white"
text_type="ascii_with_newline"
+ commit_on_focus_lost="true"
top_pad="5"
width="290"
wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml
index 9a9fd32a77..3c8f415860 100644
--- a/indra/newview/skins/default/xui/en/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/en/floater_display_name.xml
@@ -23,7 +23,7 @@
use_ellipses="true"
width="380"
wrap="true">
- The name you give your avatar is called your Display Name. You can change it once a week.
+ Your display name is what other people see above your head. It is different from your login name. You can change it once a week.
</text>
<text
type="string"
@@ -85,19 +85,10 @@
width="120" />
<button
height="23"
- label="Reset"
- layout="topleft"
- font="SansSerif"
- left_pad="5"
- name="reset_btn"
- tool_tip="Make Display Name the same as Username"
- width="120" />
- <button
- height="23"
label="Cancel"
font="SansSerif"
layout="topleft"
- left_pad="5"
+ left_pad="125"
name="cancel_btn"
width="120" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
index d783d1e23c..e91efb89b2 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="466"
+ height="486"
layout="topleft"
name="Inventory Finder"
help_topic="inventory_finder"
@@ -95,12 +95,29 @@
width="126" />
<icon
height="16"
+ image_name="Inv_Material"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_material"
+ top="122"
+ width="16" />
+ <check_box
+ height="16"
+ label="Materials"
+ layout="topleft"
+ left_pad="2"
+ name="check_material"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
image_name="Inv_Notecard"
layout="topleft"
left="8"
mouse_opaque="true"
name="icon_notecard"
- top="122"
+ top="142"
width="16" />
<check_box
height="16"
@@ -117,7 +134,7 @@
left="8"
mouse_opaque="true"
name="icon_object"
- top="142"
+ top="162"
width="16" />
<check_box
height="16"
@@ -134,7 +151,7 @@
left="8"
mouse_opaque="true"
name="icon_script"
- top="162"
+ top="182"
width="16" />
<check_box
height="16"
@@ -151,7 +168,7 @@
left="8"
mouse_opaque="true"
name="icon_sound"
- top="182"
+ top="202"
width="16" />
<check_box
height="16"
@@ -168,7 +185,7 @@
left="8"
mouse_opaque="true"
name="icon_texture"
- top="202"
+ top="222"
width="16" />
<check_box
height="16"
@@ -185,7 +202,7 @@
left="8"
mouse_opaque="true"
name="icon_snapshot"
- top="222"
+ top="242"
width="16" />
<check_box
height="16"
@@ -202,7 +219,7 @@
left="8"
mouse_opaque="true"
name="icon_settings"
- top="242"
+ top="262"
width="16" />
<check_box
height="16"
@@ -220,7 +237,7 @@
layout="topleft"
left="8"
name="All"
- top="262"
+ top="282"
width="100" />
<button
height="20"
@@ -274,7 +291,7 @@
width="260"/>
<check_box
height="16"
- top="352"
+ top="372"
label="Since Logoff"
layout="topleft"
left_delta="0"
@@ -290,7 +307,7 @@
layout="topleft"
left_delta="0"
name="- OR -"
- top="370"
+ top="390"
width="144">
- OR -
</text>
@@ -298,7 +315,7 @@
height="16"
layout="topleft"
name="date_search_direction"
- top="388"
+ top="408"
left="8"
width="270">
<radio_item
@@ -368,6 +385,6 @@
layout="topleft"
name="Close"
right="-6"
- top="434"
+ top="454"
width="76" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
index b8893e11d9..9639e70544 100644
--- a/indra/newview/skins/default/xui/en/floater_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
@@ -16,11 +16,35 @@
width="200">
<floater.string
name="ToolTipMsg">
- [REGION](Double-click to open Map, shift-drag to pan)
+ [PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG]
+ </floater.string>
+ <floater.string
+ name="ParcelNameMsg">
+ [PARCEL_NAME]
+ </floater.string>
+ <floater.string
+ name="ParcelSalePriceMsg">
+ Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²)
+ </floater.string>
+ <floater.string
+ name="ParcelSaleAreaMsg">
+ Area: [AREA]m²
+ </floater.string>
+ <floater.string
+ name="ParcelOwnerMsg">
+ Owner: [PARCEL_OWNER]
+ </floater.string>
+ <floater.string
+ name="RegionNameMsg">
+ Region: [REGION_NAME]
</floater.string>
<floater.string
- name="AltToolTipMsg">
- [REGION](Double-click to teleport, shift-drag to pan)
+ name="ToolTipHintMsg">
+ Double-click to open map
+ </floater.string>
+ <floater.string
+ name="AltToolTipHintMsg">
+ Double-click to teleport
</floater.string>
<floater.string name="mini_map_caption">
Mini-map
@@ -37,105 +61,73 @@
<text
type="string"
length="1"
- bottom="218"
label="N"
layout="topleft"
- left="0"
name="floater_map_north"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
N
</text>
<text
type="string"
length="1"
- bottom="218"
label="E"
layout="topleft"
- left="0"
name="floater_map_east"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
E
</text>
<text
type="string"
length="1"
- bottom="205"
label="W"
layout="topleft"
- left="0"
name="floater_map_west"
- right="11"
- text_color="1 1 1 0.7"
- top="175">
+ text_color="1 1 1 0.7">
W
</text>
<text
type="string"
length="1"
- bottom="218"
label="S"
layout="topleft"
- left="0"
name="floater_map_south"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
S
</text>
<text
type="string"
length="1"
- bottom="218"
label="SE"
layout="topleft"
- left="0"
name="floater_map_southeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SE
</text>
<text
type="string"
length="1"
- bottom="218"
label="NE"
layout="topleft"
- left="0"
name="floater_map_northeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NE
</text>
<text
type="string"
length="1"
- bottom="218"
label="SW"
layout="topleft"
- left="0"
name="floater_map_southwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SW
</text>
<text
type="string"
length="1"
- bottom="218"
label="NW"
layout="topleft"
- left="0"
name="floater_map_northwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NW
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml
new file mode 100644
index 0000000000..434123faf0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml
@@ -0,0 +1,532 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ default_tab_group="1"
+ height="887"
+ width="256"
+ min_height="500"
+ min_width="256"
+ layout="topleft"
+ name="material editor"
+ help_topic="material_editor"
+ title="[MATERIAL_NAME]">
+ <string name="no_upload_fee_string">no upload fee</string>
+ <string name="upload_fee_string">L$[FEE] upload fee</string>
+ <string name="material_selection_title">Material selection</string>
+ <string name="material_selection_text">Select material:</string>
+ <string name="material_override_title">Material override</string>
+
+ <scroll_container
+ name="materials_scroll"
+ top="14"
+ left="4"
+ height="768"
+ width="247"
+ follows="all"
+ layout="topleft"
+ color="DkGray2"
+ opaque="true"
+ reserve_scroll_corner="false"
+ >
+ <panel
+ border="false"
+ name="scroll_panel"
+ top="0"
+ left="0"
+ height="768"
+ width="247"
+ >
+ <check_box
+ follows="left|top"
+ label="Double Sided"
+ left="10"
+ top="0"
+ name="double sided"
+ height="25"
+ width="120" />
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="196"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="base_color_texture_pnl"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="128">
+ Base Color:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="base_color_texture"
+ tool_tip="Base Color map. Alpha channel is optional and used for transparency."
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="base_color_upload_fee"
+ >
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ >
+ Tint
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="base color"
+ width="40" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Transparency
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="transparency"
+ width="64"
+ />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label alphamode"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="5"
+ width="90">
+ Alpha mode
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="alpha mode"
+ top_pad="4"
+ width="96">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="OPAQUE" />
+ <combo_box.item
+ label="Alpha blending"
+ name="Alpha blending"
+ value="BLEND" />
+ <combo_box.item
+ label="Alpha masking"
+ name="Alpha masking"
+ value="MASK" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Alpha Cutoff
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="alpha cutoff"
+ width="64"
+ />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="metallic_texture_pnl"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ >
+ Metallic-Roughness:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ width="128"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="metallic_roughness_texture"
+ tool_tip="GLTF metallic-roughness map with optional occlusion. Red channel is occlusion, green channel is roughness, blue channel is metalness."
+ top_pad="8"
+ />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="metallic_upload_fee"
+ >
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ >
+ Metallic Factor
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="metalness factor"
+ width="64"
+ />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Roughness Factor
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="roughness factor"
+ width="64"
+ />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="emissive_texture_pnl"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64">
+ Emissive:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="emissive_texture"
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="emissive_upload_fee"
+ >
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ >
+ Tint
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="emissive color"
+ width="40" />
+ <!--<text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="64"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ >
+ Intensity
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ max_val="100"
+ width="64"
+ />-->
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ top_pad="5"
+ name="normal_texture_pnl"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64">
+ Normal:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="normal_texture"
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="normal_upload_fee"
+ >
+ No upload fee
+ </text>
+ </panel>
+ </panel>
+ </scroll_container>
+
+ <panel
+ follows="right|bottom"
+ width="246"
+ height="97"
+ layout="bottomright"
+ top_pad="0"
+ left="5"
+ name="button_panel"
+ >
+ <text
+ type="string"
+ name="unsaved_changes"
+ font.style="BOLD"
+ text_color="DrYellow"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="200"
+ layout="topleft"
+ left="10"
+ top="0"
+ >
+ Usaved changes
+ </text>
+ <button
+ follows="left|top"
+ height="25"
+ label="Save"
+ layout="topleft"
+ name="save"
+ top_pad="7"
+ left="0"
+ width="120" />
+ <button
+ follows="left|top"
+ height="25"
+ label="Save As..."
+ layout="topleft"
+ name="save_as"
+ top_delta="0"
+ left_pad="6"
+ width="120" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="220"
+ layout="topleft"
+ left="10"
+ top_pad="5"
+ name="total_upload_fee"
+ >
+ Total upload fee: L$ [FEE]
+ </text>
+
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="button_border"
+ top_pad="7"
+ width="246"/>
+
+ <button
+ follows="left|top"
+ height="25"
+ label="Cancel"
+ layout="topleft"
+ name="cancel"
+ top_pad="7"
+ left="61"
+ width="121" />
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index e499ddbc2f..21c894d3af 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -830,6 +830,7 @@
<combo_item name="physics_medium"> Medium </combo_item>
<combo_item name="physics_low"> Low </combo_item>
<combo_item name="physics_lowest"> Lowest </combo_item>
+ <combo_item name="physics_bounding_box"> Bounding Box </combo_item>
<combo_item name="load_from_file"> From file </combo_item>
</combo_box>
<line_editor
diff --git a/indra/newview/skins/default/xui/en/floater_my_environments.xml b/indra/newview/skins/default/xui/en/floater_my_environments.xml
index 6aff387dcb..db81c8bba2 100644
--- a/indra/newview/skins/default/xui/en/floater_my_environments.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_environments.xml
@@ -119,7 +119,7 @@
follows="all"
layout="topleft"
name="pnl_settings"
- filter_asset_type="settings"/>
+ filter_asset_types="settings"/>
</panel>
</layout_panel>
<layout_panel
diff --git a/indra/newview/skins/default/xui/en/floater_perms_default.xml b/indra/newview/skins/default/xui/en/floater_perms_default.xml
index 49dc719a24..9ca61671e1 100644
--- a/indra/newview/skins/default/xui/en/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/en/floater_perms_default.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="250"
+ height="266"
layout="topleft"
name="perms default"
help_topic="perms_default"
@@ -10,7 +10,7 @@
width="700">
<panel
follows="left|top|right|bottom"
- height="200"
+ height="216"
label="Default Permissions"
layout="topleft"
left="10"
@@ -549,6 +549,70 @@
left_pad="0"
top_delta="0"
width="100" />
+ <text
+ name="label_14"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when GLTF Materials are created"
+ width="100">
+ Materials
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Material"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="MaterialsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="env_material_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Materials" />
+ </check_box>
+ <check_box
+ control_name="MaterialsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="env_materials_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="MaterialsNextOwnerCopy"
+ control_name="MaterialsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="env_materials_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="MaterialsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="env_materials_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="MaterialsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="env_materials_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
</panel>
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 0a4acd979a..4a08cc5285 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -272,51 +272,6 @@
Hardware
</text>
- <slider
- control_name="RenderFogRatio"
- follows="left|top"
- height="16"
- initial_value="4"
- decimal_digits="1"
- label="Fog Distance Ratio:"
- label_width="185"
- layout="topleft"
- left="30"
- name="fog"
- min_val="0.5"
- max_val="10"
- increment="0.1"
- top_delta="16"
- width="332" />
-
- <slider
- control_name="RenderGamma"
- follows="left|top"
- height="16"
- initial_value="1"
- decimal_digits="2"
- label="Gamma:"
- label_width="185"
- layout="topleft"
- left="30"
- name="gamma"
- min_val="0"
- max_val="2"
- increment="0.01"
- top_delta="16"
- width="332" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="30"
- name="(brightness, lower is brighter)"
- top_delta="16"
- width="260">
- (0 = default brightness, lower = brighter)
- </text>
<check_box
control_name="RenderAnisotropic"
@@ -585,20 +540,6 @@
</check_box>
<check_box
- control_name="RenderObjectBump"
- height="16"
- initial_value="true"
- label="Bump mapping and shiny"
- layout="topleft"
- left="420"
- name="BumpShiny"
- top_delta="16"
- width="300">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
control_name="RenderLocalLights"
height="16"
initial_value="true"
@@ -610,116 +551,6 @@
width="300" />
<slider
- control_name="RenderTerrainDetail"
- follows="left|top"
- height="16"
- label="Terrain Detail:"
- label_width="165"
- layout="topleft"
- left="440"
- show_text="false"
- initial_value="0"
- increment="1"
- min_val="0"
- max_val="1"
- name="TerrainDetail"
- top_delta="16"
- width="280" >
- <slider.commit_callback
- function="Pref.UpdateSliderText"
- parameter="TerrainDetail" />
- </slider>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- top_delta="0"
- left_delta="284"
- name="TerrainDetailText"
- text_readonly_color="LabelDisabledColor"
- width="65">
- Low
- </text>
-
- <check_box
- control_name="RenderAvatarCloth"
- height="16"
- initial_value="true"
- label="Avatar cloth"
- layout="topleft"
- left="440"
- name="AvatarCloth"
- top_delta="16"
- width="280" />
-
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- name="ReflectionsText"
- text_readonly_color="LabelDisabledColor"
- top_delta="16"
- left="440"
- width="128">
- Water Reflections:
- </text>
- <combo_box
- control_name="RenderReflectionDetail"
- height="18"
- layout="topleft"
- left_delta="170"
- top_delta="0"
- name="Reflections"
- width="150">
- <combo_box.item
- label="None; opaque"
- name="0"
- value="-2"/>
- <combo_box.item
- label="None; transparent"
- name="0"
- value="-1"/>
- <combo_box.item
- label="Minimal"
- name="0"
- value="0"/>
- <combo_box.item
- label="Terrain and trees"
- name="1"
- value="1"/>
- <combo_box.item
- label="All static objects"
- name="2"
- value="2"/>
- <combo_box.item
- label="All avatars and objects"
- name="3"
- value="3"/>
- <combo_box.item
- label="Everything"
- name="4"
- value="4"/>
- </combo_box>
-
- <check_box
- control_name="WindLightUseAtmosShaders"
- height="16"
- initial_value="true"
- label="Atmospheric shaders"
- layout="topleft"
- left="440"
- name="WindLightUseAtmosShaders"
- top_delta="16"
- width="280">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <slider
control_name="WLSkyDetail"
decimal_digits="0"
follows="left|top"
@@ -729,7 +560,7 @@
label="Sky:"
label_width="145"
layout="topleft"
- left="460"
+ left="420"
min_val="16"
max_val="128"
name="SkyMeshDetail"
@@ -755,26 +586,12 @@
</text>
<check_box
- control_name="RenderDeferred"
- height="16"
- initial_value="true"
- label="Advanced Lighting Model"
- layout="topleft"
- left="460"
- name="UseLightShaders"
- top_delta="16"
- width="260">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
control_name="RenderDeferredSSAO"
height="16"
initial_value="true"
label="Ambient Occlusion"
layout="topleft"
- left="480"
+ left="420"
name="UseSSAO"
top_delta="16"
width="240">
@@ -788,7 +605,7 @@
initial_value="true"
label="Depth of Field"
layout="topleft"
- left="480"
+ left="420"
name="UseDoF"
top_delta="16"
width="240">
@@ -796,29 +613,13 @@
function="Pref.RenderOptionUpdate" />
</check_box>
- <!--
- <check_box
- control_name="RenderUseAdvancedAtmospherics"
- height="16"
- initial_value="true"
- label="Advanced Atmospherics"
- layout="topleft"
- left="480"
- name="UseAdvancedAtmo"
- top_delta="16"
- width="240">
- <check_box.commit_callback
- function="Pref.AdvancedAtmosphericsEnable" />
- </check_box>
- -->
-
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
- left="480"
+ left="420"
name="RenderShadowDetailText"
text_readonly_color="LabelDisabledColor"
top_delta="16"
@@ -846,15 +647,53 @@
name="2"
value="2"/>
</combo_box>
-
-<!-- End of Advanced Settings block -->
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="420"
+ name="RenderReflectionDetailText"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="16"
+ width="128">
+ Reflections:
+ </text>
+ <combo_box
+ control_name="RenderReflectionProbeDetail"
+ height="18"
+ layout="topleft"
+ left_delta="130"
+ top_delta="0"
+ name="ReflectionDetial"
+ width="150">
+ <combo_box.item
+ label="Disabled"
+ name="0"
+ value="-1"/>
+ <combo_box.item
+ label="Static Only"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="Static+Dynamic"
+ name="1"
+ value="1"/>
+ <combo_box.item
+ label="Realtime"
+ name="2"
+ value="2"/>
+ </combo_box>
+
+ <!-- End of Advanced Settings block -->
<view_border
bevel_style="in"
height="0"
layout="topleft"
left="13"
name="horiz_border"
- top_pad="21"
+ top="338"
top_delta="5"
width="774"/>
<button
@@ -864,7 +703,7 @@
layout="topleft"
left="20"
name="Defaults"
- top_delta="10"
+ top_delta="20"
width="210">
<button.commit_callback
function="Pref.HardwareDefaults" />
diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
index e1e7e1c8c8..048cf7df62 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
@@ -17,94 +17,122 @@
name="Copy">
Copy To Inventory
</floater.string>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="19"
- layout="topleft"
- left="10"
- name="desc txt"
- top="21"
- width="90">
- Description:
- </text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top|right"
- font="SansSerif"
- height="19"
- layout="topleft"
- left_pad="0"
- max_length_bytes="127"
- name="desc"
- width="190" />
- <text
- type="string"
- halign="right"
- length="1"
- follows="right|bottom"
- height="16"
- layout="topleft"
- left="110"
- name="dimensions"
- top="255"
- width="200">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text
- type="string"
- halign="right"
- length="1"
- follows="right|bottom"
- height="16"
- layout="topleft"
- left_delta="-110"
- name="aspect_ratio"
- top_pad="5"
- width="200">
- Preview aspect ratio
- </text>
- <combo_box
- allow_text_entry="true"
- top_delta="-3"
- follows="right|bottom"
- height="23"
- left_pad="10"
- max_chars="20"
- mouse_opaque="true"
- enabled="true"
- width="108"
- name="combo_aspect_ratio"
- tool_tip="Preview at a fixed aspect ratio">
- </combo_box>
- <button
- follows="right|bottom"
- height="22"
- label="OK"
- layout="topleft"
- left="6"
- name="Keep"
- top_pad="5"
- width="110" />
- <button
- follows="right|bottom"
- height="22"
- label="Discard"
- layout="topleft"
- left_pad="5"
- name="Discard"
- top_delta="0"
- width="110" />
- <button
- follows="right|bottom"
- height="22"
- label="Save As"
- layout="topleft"
- left_pad="5"
- name="save_tex_btn"
- top_delta="0"
- width="110" />
+ <layout_stack
+ animate="false"
+ name="preview_stack"
+ top_pad="15"
+ left="0"
+ follows="all"
+ orientation="vertical"
+ height="350"
+ width="370"
+ layout="topleft">
+ <layout_panel
+ name="texture_panel"
+ height="305"
+ top_pad="0"
+ left="0"
+ follows="left|top"
+ layout="topleft">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="desc txt"
+ top="6"
+ width="90">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length_bytes="127"
+ name="desc"
+ width="190" />
+ <text
+ type="string"
+ halign="right"
+ length="1"
+ follows="right|bottom"
+ height="16"
+ layout="topleft"
+ left="110"
+ name="dimensions"
+ bottom="-40"
+ width="200">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text
+ type="string"
+ halign="right"
+ length="1"
+ follows="right|bottom"
+ height="16"
+ layout="topleft"
+ left_delta="-110"
+ name="aspect_ratio"
+ top_pad="5"
+ width="200">
+ Preview aspect ratio
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ top_delta="-3"
+ follows="right|bottom"
+ height="23"
+ left_pad="10"
+ max_chars="20"
+ mouse_opaque="true"
+ enabled="true"
+ width="108"
+ name="combo_aspect_ratio"
+ tool_tip="Preview at a fixed aspect ratio">
+ </combo_box>
+ </layout_panel>
+ <layout_panel
+ name="buttons_panel"
+ height="45"
+ bottom="-40"
+ left="0"
+ follows="right|bottom"
+ auto_resize="false"
+ layout="topleft">
+ <button
+ follows="right|bottom"
+ height="22"
+ label="OK"
+ layout="topleft"
+ left="6"
+ name="Keep"
+ top_pad="0"
+ width="110" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Discard"
+ layout="topleft"
+ left_pad="5"
+ name="Discard"
+ top_delta="0"
+ width="110" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Save As"
+ layout="topleft"
+ left_pad="5"
+ name="save_tex_btn"
+ top_delta="0"
+ width="110" />
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile.xml b/indra/newview/skins/default/xui/en/floater_profile.xml
new file mode 100644
index 0000000000..32ab811a6e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater
+ name="avatarinfo"
+ height="510"
+ width="510"
+ layout="topleft"
+ can_close="true"
+ can_resize="true"
+ help_topic="panel_my_profile_tab"
+ min_height="510"
+ min_width="510"
+ positioning="centered"
+ save_rect="true"
+ title="Profile"
+>
+ <panel
+ name="panel_profile_view"
+ top="0"
+ left="0"
+ height="500"
+ width="505"
+ follows="all"
+ class="panel_profile"
+ >
+ <tab_container
+ name="panel_profile_tabs"
+ top_pad="5"
+ left="0"
+ height="500"
+ width="505"
+ follows="all"
+ layout="topleft"
+ halign="center"
+ tab_min_width="81"
+ tab_height="30"
+ tab_position="top"
+ >
+ <panel
+ name="panel_profile_secondlife"
+ label="BIO"
+ layout="topleft"
+ class="panel_profile_secondlife"
+ filename="panel_profile_secondlife.xml"
+ help_topic="profile_secondlife_tab"
+ />
+ <panel
+ name="panel_profile_web"
+ label="FEED"
+ layout="topleft"
+ class="panel_profile_web"
+ filename="panel_profile_web.xml"
+ help_topic="profile_web_tab"
+ />
+ <panel
+ name="panel_profile_picks"
+ label="PICKS"
+ layout="topleft"
+ class="panel_profile_picks"
+ filename="panel_profile_picks.xml"
+ help_topic="profile_picks_tab"
+ />
+ <panel
+ name="panel_profile_classifieds"
+ label="CLASSIFIEDS"
+ layout="topleft"
+ class="panel_profile_classifieds"
+ filename="panel_profile_classifieds.xml"
+ help_topic="profile_classified_tab"
+ />
+ <panel
+ name="panel_profile_firstlife"
+ label="REAL LIFE"
+ layout="topleft"
+ class="panel_profile_firstlife"
+ filename="panel_profile_firstlife.xml"
+ help_topic="profile_firstlife_tab"
+ />
+ <panel
+ name="panel_profile_notes"
+ label="MY NOTES"
+ layout="topleft"
+ class="panel_profile_notes"
+ filename="panel_profile_notes.xml"
+ help_topic="profile_notes_tab"
+ />
+ </tab_container>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_permissions.xml b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml
new file mode 100644
index 0000000000..9f3b4d9a00
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ bg_opaque_image="Window_NoTitle_Foreground"
+ bg_alpha_image="Window_NoTitle_Background"
+ height="115"
+ layout="topleft"
+ name="profile_permissions"
+ width="300">
+ <string
+ name="description_string"
+ value="Allow [AGENT_NAME] to:" />
+ <text
+ name="perm_description"
+ value="Allow agent to:"
+ top="1"
+ left="12"
+ right="-6"
+ height="16"
+ follows="top|left"
+ layout="topleft"
+ font.style="BOLD"
+ />
+ <check_box
+ name="online_check"
+ label="See when I am online"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <check_box
+ name="map_check"
+ label="Find me on the world map"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <check_box
+ name="objects_check"
+ label="Edit, delete or take my objects from my land"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <button
+ name="perms_btn_ok"
+ label="OK"
+ top_pad="5"
+ left="42"
+ height="20"
+ width="100"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="perms_btn_cancel"
+ label="Cancel"
+ top_delta="0"
+ left_pad="12"
+ height="20"
+ width="100"
+ follows="top|left"
+ layout="topleft"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_texture.xml b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
new file mode 100644
index 0000000000..3b351a3325
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ height="223"
+ width="200"
+ layout="topleft"
+ min_height="128"
+ min_width="128"
+ name="profile_texture">
+ <layout_stack
+ name="preview_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ orientation="vertical"
+ layout="topleft"
+ animate="false">
+ <layout_panel
+ name="texture_panel"
+ height="196"
+ follows="left|top"
+ auto_resize="true"
+ layout="topleft">
+ <icon
+ name="profile_pic"
+ image_name="Generic_Person_Large"
+ layout="topleft"
+ follows="all"
+ top="5"
+ left="5"
+ bottom="-1"
+ right="-5"/>
+ </layout_panel>
+ <layout_panel
+ name="buttons_panel"
+ height="26"
+ auto_resize="false"
+ layout="topleft">
+ <layout_stack
+ name="buttons_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ orientation="horizontal"
+ layout="topleft"
+ animate="false">
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="close_panel"
+ auto_resize="false"
+ width="112">
+ <button
+ follows="top|left"
+ height="22"
+ label="Close"
+ layout="topleft"
+ left="1"
+ top="0"
+ width="110"
+ name="close_btn"/>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index d07e3cb31b..343e72f057 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -11,6 +11,11 @@
name="Screenshot">
Screenshot
</floater.string>
+ <floater.string
+ name="chat_report_format">
+Time: [MSG_TIME]
+Text: [MSG_DESCRIPTION]
+ </floater.string>
<texture_picker
allow_no_texture="true"
default_image_name="None"
@@ -19,7 +24,7 @@
layout="topleft"
left="60"
name="screenshot"
- top="15"
+ top="20"
width="220" />
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_settings_picker.xml b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
index 3a26c3b547..8931269fe7 100644
--- a/indra/newview/skins/default/xui/en/floater_settings_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
@@ -89,7 +89,7 @@
top="1"
right="-4"
bottom="-1"
- filter_asset_type="settings" />
+ filter_asset_types="settings" />
</panel>
</layout_panel>
<layout_panel name="pnl_combo"
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index 3a66911389..0cb69137e3 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -138,6 +138,7 @@
word_wrap="true"
visible="false"
width="87" />
+
<filter_editor
follows="left|top|right"
height="23"
@@ -153,22 +154,13 @@
bg_alpha_color="DkGray2"
border="false"
follows="all"
- height="233"
+ height="242"
layout="topleft"
left_delta="0"
name="inventory panel"
top_pad="4"
width="231"
- filter_asset_type="texture"/>
- <check_box
- height="14"
- initial_value="false"
- label="Show folders"
- layout="topleft"
- name="show_folders_check"
- top_pad="0"
- left_delta="-3"
- width="200" />
+ filter_asset_types="texture|material"/>
<!-- middle: local mode -->
<button
@@ -218,8 +210,8 @@
multi_select="true"
search_column="1"
visible="false">
+ <column name="icon" label="" width="20" />
<column name="unit_name" label="Name" dynamicwidth="true" />
- <column name="unit_id_HIDDEN" label="ID" width="0" />
</scroll_list>
<!-- middle: bake mode -->
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 0abee2ff80..4700488197 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2,7 +2,7 @@
<floater
positioning="cascading"
legacy_header_height="18"
- height="600"
+ height="651"
layout="topleft"
bg_opaque_image="Window_NoTitle_Foreground"
bg_alpha_image="Window_NoTitle_Background"
@@ -68,7 +68,7 @@
</floater.string>
<floater.string
name="status_selectcount">
- [OBJ_COUNT] objects selected, land impact [LAND_IMPACT]
+ [OBJ_COUNT] objects selected, land impact [LAND_IMPACT] [secondlife:///app/openfloater/object_weights More info]
</floater.string>
<floater.string
name="status_remaining_capacity">
@@ -763,11 +763,12 @@
font="SansSerifSmall"
layout="topleft"
left="10"
- name="selection_count"
+ name="selection_faces"
top_delta="0"
visible="false"
width="280">
- </text>
+ Faces selected: [FACES_STRING]
+ </text>
<text
text_color="LtGray_50"
type="string"
@@ -777,11 +778,10 @@
font="SansSerifSmall"
layout="topleft"
left="10"
- name="remaining_capacity"
+ name="selection_count"
top_pad="0"
visible="false"
width="280">
- [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights More info]
</text>
<!-- <text -->
<!-- text_color="LtGray_50" -->
@@ -820,7 +820,7 @@
width="282"/>
<tab_container
follows="left|top"
- height="410"
+ height="476"
halign="center"
left="0"
name="Object Info Tabs"
@@ -1430,16 +1430,40 @@ even though the user gets a free copy.
tool_tip="Causes object to not collide with other objects or avatars"
top_pad="0"
width="123" />
- <text
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left_delta="0"
+ name="object_horizontal"
+ top_pad="10"
+ width="95" />
+ <menu_button
+ menu_filename="menu_copy_paste_pos.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_pos_btn"
+ tool_tip="Paste options"
+ width="19"/>
+ <text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
name="label position"
- top_pad="10"
+ tool_tip="Position (meters)"
+ left_pad="8"
+ top_delta="0"
width="121">
- Position (meters)
+ Position (m)
</text>
<spinner
follows="left|top"
@@ -1449,12 +1473,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="512"
min_val="-256"
name="Pos X"
text_enabled_color="1 0 0.3 .7"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
follows="left|top"
@@ -1481,21 +1505,36 @@ even though the user gets a free copy.
layout="topleft"
left_delta="0"
max_val="4096"
+ min_val="-32"
name="Pos Z"
text_enabled_color="0 0.8 1 .65"
top_pad="3"
width="87" />
+ <menu_button
+ menu_filename="menu_copy_paste_size.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_size_btn"
+ tool_tip="Paste options"
+ width="19"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left_pad="8"
+ top_delta="0"
name="label size"
- top_pad="6"
+ tool_tip="Size (meters)"
width="121">
- Size (meters)
+ Size (m)
</text>
<spinner
follows="left|top"
@@ -1505,12 +1544,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="64"
min_val="0.01"
name="Scale X"
text_enabled_color="1 1 1 1"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
follows="left|top"
@@ -1542,17 +1581,31 @@ even though the user gets a free copy.
text_enabled_color="1 1 1 1"
top_pad="3"
width="87" />
+ <menu_button
+ menu_filename="menu_copy_paste_rot.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_rot_btn"
+ tool_tip="Paste options"
+ width="19"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left_pad="8"
+ top_delta="0"
name="label rotation"
- top_pad="10"
+ tool_tip="Rotation (degrees)"
width="121">
- Rotation (degrees)
+ Rotation (°)
</text>
<spinner
decimal_digits="2"
@@ -1563,12 +1616,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="9999"
min_val="-9999"
name="Rot X"
text_enabled_color="1 1 1 1"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
decimal_digits="2"
@@ -1614,13 +1667,23 @@ even though the user gets a free copy.
width="150">
Prim Type
</text>-->
+
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ layout="topleft"
+ name="object_vertical"
+ left="117"
+ top="6"
+ height="500"
+ width="0"/>
<combo_box
height="19"
layout="topleft"
name="comboBaseType"
top="6"
left="125"
- width="150">
+ width="125">
<combo_box.item
label="Box"
name="Box"
@@ -1654,13 +1717,26 @@ even though the user gets a free copy.
name="Sculpted"
value="Sculpted" />
</combo_box>
+ <menu_button
+ menu_filename="menu_copy_paste_object.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left_pad="8"
+ top_delta="2"
+ name="clipboard_obj_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left="125"
name="text cut"
top_pad="5"
width="150">
@@ -1700,7 +1776,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text hollow"
- top_pad="6"
+ top_pad="7"
width="68">
Hollow
</text>
@@ -1748,7 +1824,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="Hollow Shape"
- top_pad="4"
+ top_pad="7"
width="150">
Hollow Shape
</text>
@@ -1784,7 +1860,7 @@ even though the user gets a free copy.
layout="topleft"
left_delta="0"
name="text twist"
- top_pad="5"
+ top_pad="7"
width="150">
Twist (begin/end)
</text>
@@ -1826,12 +1902,12 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="scale_taper"
- top_pad="3"
+ top_pad="7"
width="150">
Taper
</text>
<text
- visible="false"
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1879,7 +1955,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text topshear"
- top_pad="3"
+ top_pad="5"
width="141">
Top Shear
</text>
@@ -1922,12 +1998,12 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="advanced_cut"
- top_pad="3"
+ top_pad="7"
width="150">
Profile Cut (begin/end)
</text>
<text
- visible="false"
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1986,7 +2062,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text taper2"
- top_pad="3"
+ top_pad="7"
width="150">
Taper
</text>
@@ -2029,7 +2105,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text radius delta"
- top_pad="2"
+ top_pad="7"
width="78">
Radius
</text>
@@ -2157,6 +2233,19 @@ even though the user gets a free copy.
<panel.string name="None">None</panel.string>
<panel.string name="Prim">Prim</panel.string>
<panel.string name="Convex Hull">Convex Hull</panel.string>
+ <menu_button
+ menu_filename="menu_copy_paste_features.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top="8"
+ name="clipboard_features_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
@@ -2309,6 +2398,15 @@ even though the user gets a free copy.
name="FlexForceZ"
top_pad="4"
width="128" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="8"
+ name="object_horizontal"
+ top_pad="10"
+ width="278" />
<check_box
height="16"
@@ -2317,7 +2415,7 @@ even though the user gets a free copy.
left="10"
name="Light Checkbox Ctrl"
tool_tip="Causes object to emit light"
- top_pad="15"
+ top_pad="8"
width="60" />
<color_swatch
can_apply_immediately="true"
@@ -2344,6 +2442,19 @@ even though the user gets a free copy.
name="light texture control"
tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)"
width="32" />
+ <menu_button
+ menu_filename="menu_copy_paste_light.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top_delta="0"
+ name="clipboard_light_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<spinner
follows="left|top"
height="19"
@@ -2353,7 +2464,7 @@ even though the user gets a free copy.
layout="topleft"
left="10"
name="Light Intensity"
- top_pad="3"
+ top_pad="26"
width="128" />
<spinner bottom_delta="0"
decimal_digits="3"
@@ -2420,7 +2531,70 @@ even though the user gets a free copy.
mouse_opaque="true"
name="Light Ambiance"
width="120" />
- <text
+ <check_box
+ height="16"
+ label="Reflection Probe"
+ layout="topleft"
+ left="10"
+ name="Reflection Probe"
+ tool_tip="Adjusts how objects within this volume receive reflections when PBR is enabled"
+ top_pad="10"
+ width="60" />
+ <combo_box
+ height="19"
+ top_delta="0"
+ left="144"
+ follows="left|top"
+ name="Probe Volume Type"
+ tool_tip="Choose the probe influence volume"
+ width="108">
+ <combo_box.item
+ label="Sphere"
+ name="Sphere"
+ value="Sphere" />
+ <combo_box.item
+ label="Box"
+ name="Box"
+ value="Box"/>
+ </combo_box>
+ <check_box
+ height="16"
+ label="Dynamic"
+ layout="topleft"
+ left="10"
+ name="Probe Dynamic"
+ tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume."
+ bottom_delta="19"
+ width="60" />
+ <spinner bottom_delta="19"
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.05"
+ initial_value="0"
+ label="Ambiance"
+ label_width="55"
+ left="10"
+ max_val="1"
+ min_val="0"
+ mouse_opaque="true"
+ name="Probe Ambiance"
+ width="120" />
+ <spinner bottom_delta="0"
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.05"
+ initial_value="0"
+ label="Near Clip"
+ label_width="55"
+ left="144"
+ max_val="1024"
+ min_val="0"
+ mouse_opaque="true"
+ name="Probe Near Clip"
+ width="120" />
+ <text
type="string"
length="1"
follows="left|top"
@@ -2575,7 +2749,7 @@ even though the user gets a free copy.
border_visible="true"
bevel_style="in"
follows="left|top|right"
- height="325"
+ height="387"
layout="topleft"
left="10"
name="contents_inventory"
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index 83407069d2..c965a4427c 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -14,6 +14,31 @@
single_instance="true"
title="WORLD MAP"
width="650">
+ <string
+ name="collapse_icon"
+ value="map_ui_collapse_icon.png"/>
+ <string
+ name="expand_icon"
+ value="map_ui_expand_icon.png"/>
+ <string
+ name="collapse_tooltip"
+ value="Hide map controls"/>
+ <string
+ name="expand_tooltip"
+ value="Show map controls"/>
+ <layout_stack
+ animate="false"
+ follows="all"
+ name="floater_map_stack"
+ tab_group="1"
+ top="16"
+ left="0"
+ right="-1"
+ bottom="-1">
+ <layout_panel
+ name="map_lp"
+ width="385"
+ height="575">
<panel
filename="panel_world_map.xml"
follows="all"
@@ -21,17 +46,48 @@
layout="topleft"
left="10"
name="objects_mapview"
- top="25"
+ top="6"
width="375" />
+ <panel
+ follows="top|right"
+ height="30"
+ layout="topleft"
+ left_pad="-29"
+ name="expand_btn_panel"
+ background_visible="true"
+ bg_opaque_color="FloaterFocusBackgroundColor"
+ bg_alpha_color="FloaterDefaultBackgroundColor"
+ background_opaque="true"
+ tool_tip="Hide map controls"
+ top="350"
+ width="30">
+ <icon
+ follows="top|right"
+ height="16"
+ width="16"
+ top="7"
+ left="7"
+ scale_image="false"
+ image_name="map_ui_collapse_icon.png"
+ layout="topleft"
+ mouse_opaque="true"
+ name="expand_collapse_icon"
+ tool_tip="Hide map controls" />
+ </panel>
+ </layout_panel>
+ <layout_panel
+ height="575"
+ width="265"
+ expanded_min_dim="265"
+ name="controls_lp">
<panel
- name="layout_panel_1"
- height="22"
- width="238"
- follows="right|top"
- top="25"
- left_pad="5"
- background_visible="true"
- bg_alpha_color="DkGray2">
+ name="layout_panel_1"
+ height="22"
+ width="238"
+ follows="right|top"
+ top="6"
+ background_visible="true"
+ bg_alpha_color="DkGray2">
<text
text_color="White"
font="SansSerifLarge"
@@ -43,17 +99,17 @@
layout="topleft"
left="15"
name="events_label"
- top="3"
width="215">
Legend
</text>
</panel>
-<panel
- follows="right|top"
- height="126"
- top_pad="0"
- width="238"
- name="layout_panel_2">
+ <panel
+ follows="right|top"
+ height="126"
+ top_pad="4"
+ width="238"
+ left="1"
+ name="layout_panel_2">
<button
follows="right|top"
height="22"
@@ -677,6 +733,7 @@
name="zoom_icon"
top_pad="7"
width="16" ></icon>
+ <!-- NOTE: min_val for zoom slider is hardcoded for performance reasons -->
<slider
follows="left|bottom"
height="16"
@@ -684,10 +741,12 @@
initial_value="-2"
left_pad="0"
layout="topleft"
- max_val="0"
+ max_val="4"
min_val="-8"
name="zoom slider"
show_text="false"
width="200" />
</panel>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index ef4f19cd4c..fceb9b2184 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -85,6 +85,8 @@
use_ellipses="true" />
<text
follows="left|top|right"
+ trusted_content="false"
+ always_show_icons="true"
height="35"
left="8"
name="user_details"
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index 9885e37cea..842184de88 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -8,6 +8,16 @@
tab_stop="false"
name="main_view"
width="1024">
+
+ <!-- At the moment layout_stack is not an LLUICtrl,
+ but Tab requires focus_root to function and focus_root
+ functionality is implemented in LLUICtrl -->
+ <panel follows="all"
+ height="768"
+ name="menu_tab_wrapper"
+ mouse_opaque="false"
+ focus_root="true"
+ top="0">
<layout_stack border_size="0"
follows="all"
mouse_opaque="false"
@@ -18,12 +28,12 @@
<layout_panel mouse_opaque="true"
follows="left|right|top"
name="status_bar_container"
- tab_stop="false"
height="19"
left="0"
top="0"
width="1024"
auto_resize="false"
+ default_tab_group="1"
visible="true">
<view mouse_opaque="false"
follows="all"
@@ -31,13 +41,13 @@
left="0"
top="0"
width="1024"
+ tab_group="1"
height="19"/>
</layout_panel>
<layout_panel auto_resize="false"
height="34"
mouse_opaque="false"
name="nav_bar_container"
- tab_stop="false"
width="1024"
visible="false"/>
<layout_panel auto_resize="true"
@@ -99,6 +109,7 @@
tab_stop="false"/>
</layout_panel>
</layout_stack>
+ </panel> <!--menu_tab_wrapper-->
<panel top="0"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 26b1c86c53..630a1981df 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -13,6 +13,22 @@
function="EnableEdit" />
</menu_item_call>
<menu_item_call
+ label="Edit PBR Material"
+ name="EditGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.EditGLTFMaterial" />
+ <menu_item_call.on_enable
+ function="Object.EnableEditGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Save material to inventory"
+ name="SaveGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.SaveGLTFMaterial" />
+ <menu_item_call.on_enable
+ function="Object.EnableSaveGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
enabled="false"
label="Detach item"
layout="topleft"
@@ -33,6 +49,13 @@
function="Object.EnableTouch"
name="EnableTouch"/>
</menu_item_call>
+ <menu_item_call
+ label="Show in inventory"
+ layout="topleft"
+ name="Show original">
+ <menu_item_call.on_click
+ function="Object.ShowOriginal" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
index 05ab4d35a0..9f394a4c74 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -96,6 +96,13 @@
name="Pay">
<on_click function="AvatarIcon.Action" parameter="pay" />
</menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <on_click function="AvatarIcon.Action" parameter="report_abuse" />
+ <on_enable function="AvatarIcon.Enable" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index 500b6fffc2..20f3ad080b 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -290,4 +290,11 @@
<menu_item_call.on_visible
function="EnableMuteParticle" />
</menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call label="View Profile"
+ layout="topleft"
+ name="show_avatar_profile">
+ <menu_item_call.on_click
+ function="Avatar.ToggleMyProfile" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index ed362b36e5..59e6106a28 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -132,6 +132,13 @@
<on_click function="Avatar.DoToSelected" parameter="pay" />
<on_enable function="Avatar.EnableItem" parameter="can_pay" />
</menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="report_abuse">
+ <on_click function="Avatar.DoToSelected" parameter="report_abuse" />
+ <on_enable function="Avatar.EnableItem" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml
new file mode 100644
index 0000000000..4c12180daf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Color Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="color_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="color_paste" />
+ <on_enable function="PanelFace.menuEnable" parameter="color_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml
new file mode 100644
index 0000000000..4823d74a26
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Features Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="features_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="features_paste" />
+ <on_enable function="PanelVolume.menuEnable" parameter="features_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml
new file mode 100644
index 0000000000..5de23dfee3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Light Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="light_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="light_paste" />
+ <on_enable function="PanelVolume.menuEnable" parameter="light_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml
new file mode 100644
index 0000000000..bdc4537a9d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Object Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="params_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="params_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="params_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
new file mode 100644
index 0000000000..3ea95b281f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Position Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy position"
+ layout="topleft"
+ name="pos_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="pos_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste position"
+ layout="topleft"
+ name="pos_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="pos_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="pos_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
new file mode 100644
index 0000000000..06ce80f897
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Rotation Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy rotation"
+ layout="topleft"
+ name="rot_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="rot_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste rotation"
+ layout="topleft"
+ name="rot_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="rot_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
new file mode 100644
index 0000000000..7082a0e65b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Size Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy size"
+ layout="topleft"
+ name="size_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="size_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste size"
+ layout="topleft"
+ name="size_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="size_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="size_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml
new file mode 100644
index 0000000000..f358affc23
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Texture Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="texture_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="texture_paste" />
+ <on_enable function="PanelFace.menuEnable" parameter="texture_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
index 5cae643e44..359c093eff 100644
--- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
@@ -9,7 +9,7 @@
layout="topleft"
name="activate">
<on_click
- function="Gesture.Action.ToogleActiveState" />
+ function="Gesture.Action.ToggleActiveState" />
</menu_item_call>
<menu_item_call
label="Rename"
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
index 43287c6ec3..b38fae4404 100644
--- a/indra/newview/skins/default/xui/en/menu_im_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -79,6 +79,13 @@
</menu_item_call>
<menu_item_separator
layout="topleft"/>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <on_click function="Avatar.GearDoToSelected" parameter="report_abuse" />
+ <on_enable function="Avatar.EnableGearItem" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 78ca170813..46dd0ada5d 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -143,264 +143,6 @@
function="Inventory.EmptyLostAndFound"
parameter="rename" />
</menu_item_call>
- <menu_item_call
- label="New Folder"
- layout="topleft"
- name="New Folder">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="category" />
- </menu_item_call>
- <menu_item_call
- label="New Outfit"
- layout="topleft"
- name="New Outfit">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="outfit" />
- </menu_item_call>
- <menu_item_call
- label="New Script"
- layout="topleft"
- name="New Script">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="lsl" />
- </menu_item_call>
- <menu_item_call
- label="New Notecard"
- layout="topleft"
- name="New Note">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="notecard" />
- </menu_item_call>
- <menu_item_call
- label="New Gesture"
- layout="topleft"
- name="New Gesture">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="gesture" />
- </menu_item_call>
- <menu
- label="New Clothes"
- layout="topleft"
- name="New Clothes">
- <menu_item_call
- label="New Shirt"
- layout="topleft"
- name="New Shirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shirt" />
- </menu_item_call>
- <menu_item_call
- label="New Pants"
- layout="topleft"
- name="New Pants">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="pants" />
- </menu_item_call>
- <menu_item_call
- label="New Shoes"
- layout="topleft"
- name="New Shoes">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shoes" />
- </menu_item_call>
- <menu_item_call
- label="New Socks"
- layout="topleft"
- name="New Socks">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="socks" />
- </menu_item_call>
- <menu_item_call
- label="New Jacket"
- layout="topleft"
- name="New Jacket">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="jacket" />
- </menu_item_call>
- <menu_item_call
- label="New Skirt"
- layout="topleft"
- name="New Skirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="skirt" />
- </menu_item_call>
- <menu_item_call
- label="New Gloves"
- layout="topleft"
- name="New Gloves">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="gloves" />
- </menu_item_call>
- <menu_item_call
- label="New Undershirt"
- layout="topleft"
- name="New Undershirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="undershirt" />
- </menu_item_call>
- <menu_item_call
- label="New Underpants"
- layout="topleft"
- name="New Underpants">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="underpants" />
- </menu_item_call>
- <menu_item_call
- label="New Alpha Mask"
- layout="topleft"
- name="New Alpha Mask">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="alpha" />
- </menu_item_call>
- <menu_item_call
- label="New Tattoo"
- layout="topleft"
- name="New Tattoo">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="tattoo" />
- </menu_item_call>
- <menu_item_call
- label="New Universal"
- layout="topleft"
- name="New Universal">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="universal" />
- </menu_item_call>
- <menu_item_call
- label="New Physics"
- layout="topleft"
- name="New Physics">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="physics" />
- </menu_item_call>
- </menu>
- <menu
- label="New Body Parts"
- layout="topleft"
- name="New Body Parts">
- <menu_item_call
- label="New Shape"
- layout="topleft"
- name="New Shape">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shape" />
- </menu_item_call>
- <menu_item_call
- label="New Skin"
- layout="topleft"
- name="New Skin">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="skin" />
- </menu_item_call>
- <menu_item_call
- label="New Hair"
- layout="topleft"
- name="New Hair">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="hair" />
- </menu_item_call>
- <menu_item_call
- label="New Eyes"
- layout="topleft"
- name="New Eyes">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="eyes" />
- </menu_item_call>
- </menu>
- <menu
- label="New Settings"
- layout="topleft"
- name="New Settings">
- <menu_item_call
- label="New Sky"
- layout="topleft"
- name="New Sky">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="sky"/>
- <menu_item_call.on_enable
- function="Inventory.EnvironmentEnabled" />
- </menu_item_call>
- <menu_item_call
- label="New Water"
- layout="topleft"
- name="New Water">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="water"/>
- <menu_item_call.on_enable
- function="Inventory.EnvironmentEnabled" />
- </menu_item_call>
- <menu_item_call
- label="New Day Cycle"
- layout="topleft"
- name="New Day Cycle">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="daycycle"/>
- <menu_item_call.on_enable
- function="Inventory.EnvironmentEnabled" />
- </menu_item_call>
- </menu>
- <menu
- label="Use as default for"
- layout="topleft"
- name="upload_def">
- <menu_item_call
- label="Image uploads"
- layout="topleft"
- name="Image uploads">
- <menu_item_call.on_click
- function="Inventory.FileUploadLocation"
- parameter="texture" />
- </menu_item_call>
- <menu_item_call
- label="Sound uploads"
- layout="topleft"
- name="Sound uploads">
- <menu_item_call.on_click
- function="Inventory.FileUploadLocation"
- parameter="sound" />
- </menu_item_call>
- <menu_item_call
- label="Animation uploads"
- layout="topleft"
- name="Animation uploads">
- <menu_item_call.on_click
- function="Inventory.FileUploadLocation"
- parameter="animation" />
- </menu_item_call>
- <menu_item_call
- label="Model uploads"
- layout="topleft"
- name="Model uploads">
- <menu_item_call.on_click
- function="Inventory.FileUploadLocation"
- parameter="model" />
- </menu_item_call>
- </menu>
<menu
label="Change Type"
layout="topleft"
@@ -683,6 +425,283 @@
parameter="delete_system_folder" />
</menu_item_call>
<menu_item_separator
+ layout="topleft"
+ name="Create Separator" />
+ <menu_item_call
+ label="New Folder"
+ layout="topleft"
+ name="New Folder">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="category" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Outfit"
+ layout="topleft"
+ name="New Outfit">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="outfit" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Script"
+ layout="topleft"
+ name="New Script">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="lsl" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Notecard"
+ layout="topleft"
+ name="New Note">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="notecard" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gesture"
+ layout="topleft"
+ name="New Gesture">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gesture" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Material"
+ layout="topleft"
+ name="New Material">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="material" />
+ </menu_item_call>
+ <menu
+ label="New Clothes"
+ layout="topleft"
+ name="New Clothes">
+ <menu_item_call
+ label="New Shirt"
+ layout="topleft"
+ name="New Shirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Pants"
+ layout="topleft"
+ name="New Pants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Shoes"
+ layout="topleft"
+ name="New Shoes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Socks"
+ layout="topleft"
+ name="New Socks">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Jacket"
+ layout="topleft"
+ name="New Jacket">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skirt"
+ layout="topleft"
+ name="New Skirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gloves"
+ layout="topleft"
+ name="New Gloves">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Undershirt"
+ layout="topleft"
+ name="New Undershirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Underpants"
+ layout="topleft"
+ name="New Underpants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Alpha Mask"
+ layout="topleft"
+ name="New Alpha Mask">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Tattoo"
+ layout="topleft"
+ name="New Tattoo">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Universal"
+ layout="topleft"
+ name="New Universal">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="universal" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Physics"
+ layout="topleft"
+ name="New Physics">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="physics" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="New Body Parts"
+ layout="topleft"
+ name="New Body Parts">
+ <menu_item_call
+ label="New Shape"
+ layout="topleft"
+ name="New Shape">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shape" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skin"
+ layout="topleft"
+ name="New Skin">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Hair"
+ layout="topleft"
+ name="New Hair">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="hair" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Eyes"
+ layout="topleft"
+ name="New Eyes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="eyes" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="New Settings"
+ layout="topleft"
+ name="New Settings">
+ <menu_item_call
+ label="New Sky"
+ layout="topleft"
+ name="New Sky">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="sky"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Water"
+ layout="topleft"
+ name="New Water">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="water"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Day Cycle"
+ layout="topleft"
+ name="New Day Cycle">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="daycycle"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="Use as default for"
+ layout="topleft"
+ name="upload_def">
+ <menu_item_call
+ label="Image uploads"
+ layout="topleft"
+ name="Image uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="texture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Sound uploads"
+ layout="topleft"
+ name="Sound uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="sound" />
+ </menu_item_call>
+ <menu_item_call
+ label="Animation uploads"
+ layout="topleft"
+ name="Animation uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="animation" />
+ </menu_item_call>
+ <menu_item_call
+ label="Model uploads"
+ layout="topleft"
+ name="Model uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="model" />
+ </menu_item_call>
+ <menu_item_call
+ label="PBR material uploads"
+ layout="topleft"
+ name="PBR uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="pbr_material" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
layout="topleft" />
<menu_item_separator
layout="topleft" />
@@ -912,6 +931,25 @@
function="Inventory.DoToSelected"
parameter="apply_settings_parcel" />
</menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Subfolder Separator" />
+ <menu_item_call
+ label="Create folder from selected"
+ layout="topleft"
+ name="New folder from selected">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="new_folder_from_selected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Ungroup folder items"
+ layout="topleft"
+ name="Ungroup folder items">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="ungroup_folder_items" />
+ </menu_item_call>
<menu_item_separator
layout="topleft"
name="Marketplace Separator" />
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 3385a29a6c..0e193521a3 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -97,6 +97,14 @@
function="Inventory.DoCreate"
parameter="gesture" />
</menu_item_call>
+ <menu_item_call
+ label="New Material"
+ layout="topleft"
+ name="New Material">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="material" />
+ </menu_item_call>
<menu
height="175"
label="New Clothes"
diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml
index ea263d05ce..2715c916d4 100644
--- a/indra/newview/skins/default/xui/en/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml
@@ -8,63 +8,109 @@
top="724"
visible="false"
width="128">
- <menu_item_call
- label="Zoom Close"
- name="Zoom Close">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check
+ label="Zoom very close"
+ name="Zoom very close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
+ parameter="very close" />
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="very close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom close"
+ name="Zoom close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="close" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Medium"
- name="Zoom Medium">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom medium"
+ name="Zoom medium">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="medium" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Far"
- name="Zoom Far">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="medium" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom far"
+ name="Zoom far">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="far" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Default"
- name="Zoom Default">
- <menu_item_call.on_click
- function="Minimap.Zoom"
- parameter="default" />
- </menu_item_call>
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="far" />
+ </menu_item_check>
<menu_item_separator />
<menu_item_check
- label="Rotate Map"
- name="Rotate Map">
+ label="North at top"
+ name="North at top">
<menu_item_check.on_check
- control="MiniMapRotate" />
+ function="Minimap.MapOrientation.Check"
+ parameter="north_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapRotate" />
+ function="Minimap.MapOrientation.Set"
+ parameter="north_at_top" />
</menu_item_check>
<menu_item_check
- label="Auto Center"
- name="Auto Center">
+ label="Camera at top"
+ name="Camera at top">
<menu_item_check.on_check
- control="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Check"
+ parameter="camera_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Set"
+ parameter="camera_at_top" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_check
+ label="Show parcel boundaries"
+ name="Show parcel boundaries">
+ <menu_item_check.on_check
+ control="MiniMapShowPropertyLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapShowPropertyLines" />
</menu_item_check>
<menu_item_separator />
+ <menu_item_check
+ label="Auto-center map"
+ name="Auto-center map">
+ <menu_item_check.on_check
+ control="MiniMapAutoCenter" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapAutoCenter" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_call
+ label="Re-center map"
+ name="Re-center map">
+ <menu_item_call.on_click
+ function="Minimap.Center.Activate" />
+ </menu_item_call>
<menu_item_call
- label="Stop Tracking"
- name="Stop Tracking">
+ label="Stop tracking"
+ name="Stop tracking">
<menu_item_call.on_click
function="Minimap.Tracker"
parameter="task_properties" />
</menu_item_call>
<menu_item_separator />
<menu_item_call
+ label="About Land"
+ name="About Land">
+ <menu_item_call.on_click
+ function="Minimap.AboutLand" />
+ </menu_item_call>
+ <menu_item_call
label="World Map"
name="World Map">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index ce34508303..6d37c15815 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -22,6 +22,22 @@
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
+ label="Edit PBR Material"
+ name="EditGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.EditGLTFMaterial" />
+ <menu_item_call.on_enable
+ function="Object.EnableEditGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Save material to inventory"
+ name="SaveGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.SaveGLTFMaterial" />
+ <menu_item_call.on_enable
+ function="Object.EnableSaveGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
label="Build"
name="Build">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_profile_other.xml b/indra/newview/skins/default/xui/en/menu_profile_other.xml
new file mode 100644
index 0000000000..4db4d0922b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_other.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Avatar Profile Menu">
+ <menu_item_call
+ label="IM"
+ layout="topleft"
+ name="im">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="im"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Offer Teleport"
+ name="offer_teleport">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="offer_teleport"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Request Teleport"
+ name="request_teleport">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="request_teleport"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="request_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Voice call"
+ layout="topleft"
+ name="voice_call">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="voice_call"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="voice_call"/>
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="View chat history..."
+ layout="topleft"
+ name="chat_history">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="chat_history"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="chat_history"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_chat_history"/>
+ <menu_item_call
+ label="Add Friend"
+ layout="topleft"
+ name="add_friend">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="add_friend"/>
+ <menu_item_call.on_visible
+ function="Profile.EnableItem"
+ parameter="add_friend"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend"
+ layout="topleft"
+ name="remove_friend">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="remove_friend"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="remove_friend"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="invite_to_group">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="invite_to_group"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_invite_to_group"/>
+ <menu_item_call
+ label="Permissions"
+ layout="topleft"
+ name="agent_permissions">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="agent_permissions"/>
+ <menu_item_call.on_visible
+ function="Profile.EnableItem"
+ parameter="agent_permissions"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="map">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="can_show_on_map"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="can_show_on_map"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="share">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="share"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="pay">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="pay"/>
+ </menu_item_call>
+ <menu_item_check
+ label="Block/Unblock"
+ layout="topleft"
+ name="block_unblock">
+ <menu_item_check.on_click
+ function="Profile.Commit"
+ parameter="toggle_block_agent"/>
+ <menu_item_check.on_check
+ function="Profile.CheckItem"
+ parameter="toggle_block_agent"/>
+ <menu_item_check.on_enable
+ function="Profile.EnableItem"
+ parameter="toggle_block_agent"/>
+ </menu_item_check>
+ <menu_item_separator name="separator_copy_options"/>
+ <menu_item_call
+ label="Copy Display Name"
+ layout="topleft"
+ name="copy_display_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_display_name"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Name"
+ layout="topleft"
+ name="copy_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_username"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_username"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Id"
+ layout="topleft"
+ name="copy_id">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_user_id"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_profile_self.xml b/indra/newview/skins/default/xui/en/menu_profile_self.xml
new file mode 100644
index 0000000000..d0bd4000f8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_self.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Avatar Profile Menu Self">
+ <menu_item_call
+ label="Edit Display Name"
+ layout="topleft"
+ name="edit_display_name">
+ <on_click
+ function="Profile.Commit"
+ parameter="edit_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Edit Partner"
+ layout="topleft"
+ name="edit_partner">
+ <on_click
+ function="Profile.Commit"
+ parameter="edit_partner"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Upload Photo"
+ layout="topleft"
+ name="upload_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="upload_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="upload_photo"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Change Photo"
+ layout="topleft"
+ name="change_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="change_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="change_photo"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Photo"
+ layout="topleft"
+ name="remove_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="remove_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="remove_photo"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_copy_options"/>
+ <menu_item_call
+ label="Copy Display Name"
+ layout="topleft"
+ name="copy_display_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_display_name"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Name"
+ layout="topleft"
+ name="copy_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_username"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_username"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Id"
+ layout="topleft"
+ name="copy_id">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_user_id"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
index e8b6116026..5ca8be2123 100644
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -29,7 +29,14 @@
name="remove_friend">
<menu_item_call.on_click
function="Url.RemoveFriend" />
- </menu_item_call>
+ </menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="report_abuse">
+ <menu_item_call.on_click
+ function="Url.ReportAbuse" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 85c20268d0..cb2f24334c 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -47,8 +47,7 @@
label="Picks..."
name="Picks">
<menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="picks" />
+ function="ShowAgentProfilePicks" />
</menu_item_call>
<menu_item_call
label="Experiences..."
@@ -423,7 +422,9 @@
</menu_item_call>
<menu_item_call
label="Stop animations"
- name="Stop Animating My Avatar">
+ name="Stop Animating My Avatar"
+ allow_key_repeat="true"
+ shortcut="alt|shift|A">
<menu_item_call.on_click
function="Tools.StopAllAnimations" />
</menu_item_call>
@@ -471,7 +472,7 @@
layout="topleft"
name="Reset Skeleton And Animations">
<menu_item_call.on_click
- function="Avatar.ResetSkeletonAndAnimations" />
+ function="Avatar.ResetSelfSkeletonAndAnimations" />
</menu_item_call>
<menu_item_call
label="Attachment scripts..."
@@ -1417,6 +1418,15 @@ function="World.EnvPreset"
function="Tools.SelectOnlyMovableObjects"
parameter="movable" />
</menu_item_check>
+ <menu_item_check
+ label="Select Invisible Objects"
+ name="Select Invisible Objects">
+ <menu_item_check.on_check
+ control="SelectInvisibleObjects" />
+ <menu_item_check.on_click
+ function="Tools.SelectInvisibleObjects"
+ parameter="invisible" />
+ </menu_item_check>
<menu_item_check
label="Select By Surrounding"
name="Select By Surrounding">
@@ -1574,6 +1584,16 @@ function="World.EnvPreset"
<menu_item_call.on_visible
function="File.VisibleUploadModel"/>
</menu_item_call>
+ <menu_item_call
+ label="Material..."
+ layout="topleft"
+ name="Upload Material">
+ <menu_item_call.on_click
+ function="File.UploadMaterial"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUploadMaterial" />
+ </menu_item_call>
<menu_item_call
label="Bulk..."
layout="topleft"
@@ -1586,7 +1606,15 @@ function="World.EnvPreset"
parameter="" />
</menu_item_call>
</menu>
- <menu_item_separator/>
+ <menu_item_call
+ label="Material Editor"
+ name="material_editor_menu_item">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="material_editor" />
+ </menu_item_call>
+
+ <menu_item_separator/>
<menu_item_call
enabled="false"
label="Undo"
@@ -2633,6 +2661,12 @@ function="World.EnvPreset"
function="Advanced.ForceErrorBadMemoryAccess" />
</menu_item_call>
<menu_item_call
+ label="Force Bad Memory Access in Coroutine"
+ name="Force Bad Memory Access in Coroutine">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorBadMemoryAccessCoro" />
+ </menu_item_call>
+ <menu_item_call
label="Force Infinite Loop"
name="Force Infinite Loop">
<menu_item_call.on_click
@@ -2898,6 +2932,16 @@ function="World.EnvPreset"
parameter="lights" />
</menu_item_check>
<menu_item_check
+ label="Reflection Probes"
+ name="Reflection Probes">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="reflection probes" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="reflection probes" />
+ </menu_item_check>
+ <menu_item_check
label="Particles"
name="Particles">
<menu_item_check.on_check
@@ -3063,24 +3107,10 @@ function="World.EnvPreset"
<menu_item_check.on_click
function="ToggleControl"
parameter="UseOcclusion" />
- <menu_item_check.on_enable
- function="Advanced.EnableObjectObjectOcclusion" />
</menu_item_check>
<menu_item_separator />
<menu_item_check
- label="Advanced Lighting Model"
- name="Advanced Lighting Model">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDeferred" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDeferred" />
- <menu_item_check.on_enable
- function="Advanced.EnableRenderDeferred" />
- </menu_item_check>
- <menu_item_check
label=" Shadows from Sun/Moon/Projectors"
name="Shadows from Sun/Moon/Projectors">
<menu_item_check.on_check
@@ -3107,14 +3137,14 @@ function="World.EnvPreset"
<menu_item_separator />
<menu_item_check
- label="Debug GL"
+ label="Start Debug GL on next run"
name="Debug GL">
<menu_item_check.on_check
function="CheckControl"
- parameter="RenderDebugGL" />
+ parameter="RenderDebugGLSession" />
<menu_item_check.on_click
function="ToggleControl"
- parameter="RenderDebugGL" />
+ parameter="RenderDebugGLSession" />
</menu_item_check>
<menu_item_check
label="Debug Pipeline"
@@ -3236,6 +3266,13 @@ function="World.EnvPreset"
function="ToggleControl"
parameter="RenderHoverGlowEnable" />
</menu_item_check>
+ <menu_item_call
+ enabled="true"
+ label="Rebuild Reflection Probes"
+ name="Rebuild Reflection Probes">
+ <menu_item_call.on_click
+ function="Develop.RebuildReflectionProbes" />
+ </menu_item_call>
<menu_item_separator />
<menu_item_call
@@ -3312,6 +3349,18 @@ function="World.EnvPreset"
function="Advanced.DropPacket" />
</menu_item_call>
</menu>
+ <menu
+ create_jump_keys="true"
+ label="Cache"
+ name="Cache"
+ tear_off="true">
+ <menu_item_call
+ label="Purge Disk Cache"
+ name="Purge Disk Cache">
+ <menu_item_call.on_click
+ function="Advanced.PurgeDiskCache" />
+ </menu_item_call>
+ </menu>
<menu_item_call
label="Dump Scripted Camera"
name="Dump Scripted Camera">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index aa93601669..07ad2838b0 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1496,7 +1496,19 @@ Insufficient funds to create classified.
<notification
icon="alertmodal.tga"
- name="DeleteAvatarPick"
+ name="ProfileDeleteClassified"
+ type="alertmodal">
+Delete classified &lt;nolink&gt;[CLASSIFIED]&lt;/nolink&gt;?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProfileDeletePick"
type="alertmodal">
Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<tag>confirm</tag>
@@ -1507,6 +1519,32 @@ Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
</notification>
<notification
+ icon="alert.tga"
+ name="ProfileUnpublishedClassified"
+ type="alertmodal">
+ You have unpublished classifieds. They will be lost if you close the window.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="ProfileUnsavedChanges"
+ type="alertmodal">
+ You have usaved changes.
+ <tag>confirm</tag>
+ <tag>save</tag>
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Discard"
+ yestext="Save"/>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="DeleteOutfits"
type="alertmodal">
@@ -3907,7 +3945,7 @@ Are you sure you want to return objects owned by [USER_NAME]?
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH].
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
<tag>fail</tag>
</notification>
@@ -3918,7 +3956,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y].
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
</notification>
<notification
@@ -6764,6 +6802,22 @@ You don&apos;t have permission to view this notecard.
<notification
icon="notifytip.tga"
+ name="MaterialMissing"
+ type="notifytip">
+ Material is missing from database.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="MaterialNoPermissions"
+ type="notifytip">
+ You don&apos;t have permission to view this material.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
name="RezItemNoPermissions"
type="notifytip">
Insufficient permissions to rez object.
@@ -6795,6 +6849,15 @@ Please try again.
<notification
icon="notifytip.tga"
+ name="UnableToLoadMaterial"
+ type="notifytip">
+ Unable to load material.
+ Please try again.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
name="ScriptMissing"
type="notifytip">
Script is missing from database.
@@ -9025,7 +9088,64 @@ Unable to upload texture.
[REASON]
<tag>fail</tag>
</notification>
-
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotUploadMaterial"
+ type="alertmodal">
+There was a problem uploading the file
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Save Material"
+ name="SaveMaterialAs"
+ type="alertmodal">
+ <unique/>
+ Name this material:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ [DESC]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidMaterialName"
+ type="alertmodal">
+Please enter a non-empty name
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UsavedMaterialChanges"
+ type="alertmodal">
+ You have unsaved changes.
+ <form name="form">
+ <button
+ index="0"
+ name="discard"
+ text="Discard changes"/>
+ <button
+ index="1"
+ name="keep"
+ text="Keep editing"/>
+ </form>
+ </notification>
+
<notification
icon="alertmodal.tga"
name="LivePreviewUnavailable"
@@ -9040,6 +9160,29 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran
<notification
icon="alertmodal.tga"
+ name="FacePasteFailed"
+ type="alertmodal">
+Paste failed. [REASON]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FacePasteTexturePermissions"
+ type="alertmodal">
+ You applied a texture with limited permissions, object will inherit permissions from texture.
+ <usetemplate
+ ignoretext="Paste: You applied a texture with limited permissions"
+ name="notifyignore"/>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmLeaveCall"
type="alertmodal">
Are you sure you want to leave this call?
@@ -9699,6 +9842,15 @@ Attempt cancelled.
<notification
icon="alertmodal.tga"
+ name="LocalGLTFVerifyFail"
+ persist="true"
+ type="notify">
+Attempted to add an invalid or unreadable GLTF material [FNAME] which could not be opened or decoded.
+Attempt cancelled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="PathfindingReturnMultipleItems"
type="alertmodal">
You are returning [NUM_ITEMS] items. Are you sure you want to continue?
@@ -11640,7 +11792,7 @@ This Region does not support environmental settings.
<notification
icon="alertmodal.tga"
- label="Save Outfit"
+ label="Save Environmental Settings"
name="SaveSettingAs"
type="alertmodal">
<unique/>
@@ -11819,4 +11971,44 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB
</form>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ label="Create subfolder"
+ name="CreateSubfolder"
+ type="alertmodal">
+ <unique/>
+ Name the new folder:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ [DESC]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="SameFolderRequired"
+ type="alert">
+ Selected items must be in the same folder.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+<notification
+ icon="notifytip.tga"
+ name="MaterialCreated"
+ type="notifytip">
+Material successfully created. Asset ID: [ASSET_ID]
+</notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index aa1b929412..54f038c24f 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -155,6 +155,7 @@
right="-3"
mouse_opaque="true"
name="speaking_indicator"
+ tool_tip="Voice volume"
visible="true"
width="20" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index d4a2745d1d..04a0bc800d 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -38,28 +38,15 @@
name="auto_renew_off">
Disabled
</panel.string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
height="26"
layout="topleft"
- left_pad="4"
+ left="12"
name="title"
text_color="LtGray"
- top="0"
+ top="2"
value="Classified Info"
use_ellipses="true"
width="275" />
@@ -420,7 +407,7 @@
height="23"
label="Teleport"
layout="topleft"
- left="0"
+ left="2"
name="teleport_btn"
top="0"
width="101" />
@@ -443,24 +430,6 @@
top="0"
width="100" />
</layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="edit_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- name="edit_btn"
- top="0"
- width="101" />
- </layout_panel>
</layout_stack>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
deleted file mode 100644
index e846edf1d4..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ /dev/null
@@ -1,354 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- bevel_style="in"
- follows="left|top|right|bottom"
- height="569"
- label="Edit Classified"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_edit_classified"
- help_topic="profile_edit_classified"
- top="0"
- width="333">
- <panel.string
- name="location_notice">
- (will update after save)
- </panel.string>
- <string name="publish_label">
- Publish
- </string>
- <string name="save_label">
- Save
- </string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- type="string"
- length="1"
- follows="top"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="0"
- width="250">
- Edit Classified
- </text>
- <scroll_container
- color="DkGray2"
- follows="all"
- height="502"
- layout="topleft"
- left="8"
- top_pad="10"
- name="profile_scroll"
- reserve_scroll_corner="false"
- opaque="true"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="690"
- left="0"
- width="285">
- <panel
- name="snapshot_panel"
- layout="topleft"
- follows="left|top|right"
- height="197"
- left="10"
- top="10"
- width="272">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- follows="left|top|right"
- height="197"
- width="272"
- layout="topleft"
- top="0"
- left="0"
- name="classified_snapshot" />
- <icon
- height="197"
- image_name="spacer24.tga"
- layout="topleft"
- name="edit_icon"
- label=""
- tool_tip="Click to select an image"
- top="0"
- left="0"
- width="272" />
- </panel>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top="215"
- name="Name:"
- text_color="white"
- width="280">
- Title:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerif"
- height="20"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length_bytes="30"
- name="classified_name"
- prevalidate_callback="ascii"
- text_color="black"
- width="273" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top_pad="20"
- name="description_label"
- text_color="white"
- width="280">
- Description:
- </text>
- <text_editor
- follows="left|top|right"
- height="100"
- width="273"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="256"
- name="classified_desc"
- text_color="black"
- word_wrap="true" />
- <text
- type="string"
- length="1"
- font="SansSerifSmall"
- font.style="BOLD"
- follows="left|top"
- height="15"
- layout="topleft"
- left="10"
- name="location_label"
- text_color="white"
- top_pad="20"
- width="280">
- Location:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="30"
- layout="topleft"
- left="10"
- name="classified_location"
- right="-10"
- top_pad="2"
- width="280"
- word_wrap="true">
- loading...
- </text>
- <button
- follows="left|top"
- height="23"
- label="Set to Current Location"
- layout="topleft"
- left="10"
- top_pad="5"
- name="set_to_curr_location_btn"
- width="200" />
- <text
- follows="left|top"
- font.style="BOLD"
- height="10"
- layout="topleft"
- left="10"
- name="category_label"
- text_color="white"
- top_pad="15"
- value="Category:"
- width="250" />
- <combo_box
- follows="left|top"
- height="23"
- label=""
- left="10"
- name="category"
- top_pad="5"
- width="156" />
- <text
- follows="left|top"
- font.style="BOLD"
- height="10"
- layout="topleft"
- left="10"
- name="content_type_label"
- text_color="white"
- top_pad="15"
- value="Content type:"
- width="250" />
- <icons_combo_box
- follows="left|top"
- height="23"
- label="General Content"
- layout="topleft"
- left="10"
- name="content_type"
- top_pad="5"
- width="156">
- <icons_combo_box.drop_down_button
- image_overlay="Parcel_PG_Light"
- image_overlay_alignment="left"
- imgoverlay_label_space="3"
- pad_left="3"/>
- <icons_combo_box.item
- label="Moderate Content"
- name="mature_ci"
- value="Mature">
- <item.columns
- halign="center"
- type="icon"
- value="Parcel_M_Light"
- width="20"/>
- </icons_combo_box.item>
- <icons_combo_box.item
- label="General Content"
- name="pg_ci"
- value="PG">
- <item.columns
- halign="center"
- type="icon"
- value="Parcel_PG_Light"
- width="20"/>
- </icons_combo_box.item>
- </icons_combo_box>
- <check_box
- height="16"
- label="Auto renew each week"
- layout="topleft"
- left="10"
- name="auto_renew"
- top_pad="15"
- width="250" />
- <text
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="price_for_listing_label"
- text_color="white"
- top_pad="15"
- value="Price for listing:"
- width="250" />
- <spinner
- decimal_digits="0"
- follows="left|top"
- halign="left"
- height="23"
- increment="1"
- label_width="20"
- label="L$"
- v_pad="10"
- layout="topleft"
- left="10"
- value="50"
- min_val="50"
- max_val="99999"
- name="price_for_listing"
- top_pad="5"
- tool_tip="Price for listing."
- width="105" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- label="bottom_panel"
- layout="topleft"
- left="8"
- name="bottom_panel"
- top_pad="5"
- width="303">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="bottom_panel_ls"
- left="1"
- orientation="horizontal"
- top_pad="0"
- width="309">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="save_changes_btn_lp"
- auto_resize="true"
- width="156">
- <button
- follows="bottom|left|right"
- height="23"
- label="[LABEL]"
- layout="topleft"
- name="save_changes_btn"
- left="1"
- top="0"
- width="155" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- auto_resize="true"
- width="157">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- left="1"
- top="0"
- width="156" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
deleted file mode 100644
index 357a5559bf..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- bevel_style="in"
- follows="left|top|right|bottom"
- height="569"
- label="Edit Pick"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_edit_pick"
- help_topic="profile_edit_pick"
- top="0"
- width="333">
- <panel.string
- name="location_notice">
- (will update after save)
- </panel.string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="4"
- width="30"
- use_draw_context_alpha="false" />
- <text
- type="string"
- length="1"
- follows="top"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="4"
- width="250">
- Edit Pick
- </text>
- <scroll_container
- color="DkGray2"
- follows="all"
- height="501"
- layout="topleft"
- left="8"
- top_pad="9"
- name="profile_scroll"
- opaque="true"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="500"
- left="0"
- width="285">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- follows="left|top|right"
- height="197"
- width="272"
- layout="topleft"
- no_commit_on_selection="true"
- top="10"
- left="11"
- name="pick_snapshot" />
- <icon
- height="197"
- image_name="spacer24.tga"
- layout="topleft"
- name="edit_icon"
- label=""
- tool_tip="Click to select an image"
- top="10"
- left="11"
- width="286" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top="215"
- name="Name:"
- text_color="white"
- width="280">
- Title:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerif"
- height="20"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length_bytes="63"
- name="pick_name"
- text_color="black"
- width="273" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top_pad="20"
- name="description_label"
- text_color="white"
- width="280">
- Description:
- </text>
- <text_editor
- follows="left|top|right"
- height="100"
- width="273"
- hide_scrollbar="false"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="1023"
- name="pick_desc"
- spellcheck="true"
- text_color="black"
- word_wrap="true" />
- <text
- type="string"
- length="1"
- font="SansSerifSmall"
- font.style="BOLD"
- follows="left|top|right"
- height="15"
- layout="topleft"
- left="10"
- name="location_label"
- text_color="white"
- top_pad="20"
- width="280">
- Location:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="50"
- layout="topleft"
- left="10"
- name="pick_location"
- top_pad="2"
- width="280"
- word_wrap="true">
- loading...
- </text>
- <button
- follows="left|top"
- height="23"
- label="Set to Current Location"
- layout="topleft"
- left="8"
- top_pad="0"
- name="set_to_curr_location_btn"
- width="200" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- label="bottom_panel"
- layout="topleft"
- left="8"
- name="bottom_panel"
- top_pad="5"
- width="315">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="layout_stack1"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="313">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left="0"
- name="layout_panel1"
- auto_resize="true"
- width="150">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save Pick"
- layout="topleft"
- name="save_changes_btn"
- top="0"
- left="1"
- width="149" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left_pad="4"
- name="layout_panel2"
- auto_resize="true"
- width="146">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- top="0"
- left="1"
- width="145" />
- </layout_panel>
- </layout_stack>
-
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
deleted file mode 100644
index 2c7c8133d1..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ /dev/null
@@ -1,472 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- class="edit_profile_panel"
- follows="all"
- height="585"
- label="Profile Edit"
- layout="topleft"
- left="0"
- name="edit_profile_panel"
- top="0"
- width="313">
- <string
- name="CaptionTextAcctInfo">
- [ACCTTYPE]
-[PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string
- name="RegisterDateFormat">
- [REG_DATE] ([AGE])
- </string>
- <string
- name="AcctTypeResident"
- value="Resident" />
- <string
- name="AcctTypeTrial"
- value="Trial" />
- <string
- name="AcctTypeCharterMember"
- value="Charter Member" />
- <string
- name="AcctTypeEmployee"
- value="Linden Lab Employee" />
- <string
- name="PaymentInfoUsed"
- value="Payment Info Used" />
- <string
- name="PaymentInfoOnFile"
- value="Payment Info On File" />
- <string
- name="NoPaymentInfoOnFile"
- value="No Payment Info On File" />
- <string
- name="AgeVerified"
- value="Age-verified" />
- <string
- name="NotAgeVerified"
- value="Not Age-verified" />
- <string
- name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=en
- </string>
- <string
- name="my_account_link_url">
- http://secondlife.com/my
- </string>
- <string
- name="no_partner_text"
- value="None" />
- <scroll_container
- color="DkGray2"
- follows="all"
- height="537"
- min_height="300"
- layout="topleft"
- left="8"
- width="292"
- name="profile_scroll"
- reserve_scroll_corner="true"
- opaque="true"
- top="10">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- layout="topleft"
- top="0"
- height="537"
- min_height="300"
- left="0"
- width="292">
- <panel
- name="data_panel"
- follows="left|top|right"
- layout="topleft"
- top="0"
- height="537"
- min_height="300"
- left="0"
- width="292">
- <text
- top="5"
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="display_name_label"
- text_color="LtGray"
- value="Display Name:"
- width="80" />
- <text
- top="5"
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="solo_username_label"
- text_color="LtGray"
- value="Username:"
- visible="false"
- width="80" />
- <button
- name="set_name"
- layout="topleft"
- follows="top|left"
- image_overlay="Edit_Wrench"
- top="21"
- left="10"
- height="23"
- width="23"
- tool_tip="Set Display Name"/>
- <text
- follows="top|left"
- font="SansSerifBigBold"
- height="20"
- layout="topleft"
- left="10"
- name="solo_user_name"
- text_color="white"
- top_delta="3"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="false"
- width="275" />
- <text
- follows="top|left"
- font="SansSerifBigBold"
- height="20"
- layout="topleft"
- left="43"
- name="user_name"
- text_color="white"
- top_delta="0"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="true"
- width="250" />
- <text
- follows="top|left"
- font="SansSerifBold"
- height="20"
- layout="topleft"
- left_delta="0"
- name="user_name_small"
- text_color="white"
- top_delta="-4"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="false"
- wrap="true"
- width="245" />
- <text
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="user_label"
- text_color="LtGray"
- top_pad="8"
- value="Username:"
- width="70" />
- <text
- follows="top|left"
- height="20"
- layout="topleft"
- left_pad="0"
- name="user_slid"
- text_color="EmphasisColor"
- font="SansSerifBold"
- top_delta="-2"
- translate="false"
- use_ellipses="true"
- value="teststring.pleaseignore"
- wrap="true"
- width="205" />
- <panel
- name="lifes_images_panel"
- follows="left|top|right"
- height="244"
- layout="topleft"
- top="65"
- left="0"
- width="292">
- <panel
- follows="left|top"
- height="117"
- layout="topleft"
- left="10"
- name="second_life_image_panel"
- top="0"
- width="282">
- <text
- follows="left|top|right"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="0"
- top="10"
- name="second_life_photo_title_text"
- text_color="white"
- value="[SECOND_LIFE]:"
- width="100" />
- <texture_picker
- allow_no_texture="true"
- default_image_name="None"
- enabled="false"
- fallback_image="default_profile_picture.j2c"
- follows="top|left"
- height="124"
- layout="topleft"
- left="1"
- name="2nd_life_pic"
- top_pad="0"
- width="102" />
- </panel>
- <icon
- height="102"
- image_name="spacer24.tga"
- layout="topleft"
- name="2nd_life_edit_icon"
- label=""
- left="11"
- top_pad="-92"
- tool_tip="Click to select an image"
- width="102" />
- </panel>
- <text_editor
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerifSmall"
- height="102"
- layout="topleft"
- left="123"
- top="90"
- max_length="512"
- name="sl_description_edit"
- width="157"
- word_wrap="true">
- </text_editor>
- <panel
- follows="left|top"
- height="117"
- layout="topleft"
- top_pad="5"
- left="10"
- name="first_life_image_panel"
- width="285">
- <text
- follows="left|top|right"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="0"
- top_pad="10"
- name="real_world_photo_title_text"
- text_color="white"
- value="Real World:"
- width="100" />
- <texture_picker
- allow_no_texture="true"
- default_image_name="None"
- enabled="false"
- fallback_image="Generic_Person_Large"
- follows="top|left"
- height="124"
- layout="topleft"
- left="1"
- name="real_world_pic"
- top_pad="0"
- width="102" />
- </panel>
- <icon
- height="102"
- image_name="spacer24.tga"
- layout="topleft"
- name="real_world_edit_icon"
- label=""
- left="11"
- top_pad="-92"
- tool_tip="Click to select an image"
- width="102" />
- <text_editor
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerifSmall"
- height="102"
- layout="topleft"
- left="123"
- max_length="512"
- top="223"
- name="fl_description_edit"
- width="157"
- word_wrap="true">
- </text_editor>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_homepage_text"
- text_color="white"
- top_pad="10"
- width="100">
- Homepage:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerifSmall"
- height="20"
- layout="topleft"
- left="10"
- top_pad="0"
- value="http://"
- name="homepage_edit"
- width="272">
- </line_editor>
- <text
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_acc_status_text"
- text_color="white"
- top_pad="10"
- value="My Account:"
- width="100" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="28"
- layout="topleft"
- left="10"
- name="acc_status_text"
- read_only="true"
- top_pad="5"
- v_pad="0"
- value="Resident. No payment info on file."
- width="200"
- word_wrap="true" />
- <text
- type="string"
- follows="left|top"
- font="SansSerifSmall"
- height="15"
- layout="topleft"
- left="10"
- name="my_account_link"
- value="[[URL] Go to My Dashboard]"
- width="200" />
- <text
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_partner_text"
- text_color="white"
- top_pad="10"
- value="My Partner:"
- width="150" />
- <panel
- follows="left|top|right"
- height="15"
- layout="topleft"
- left="10"
- name="partner_data_panel"
- width="200">
- <text
- follows="left|top|right"
- height="12"
- initial_value="(retrieving)"
- layout="topleft"
- left="0"
- name="partner_text"
- top="0"
- use_ellipses="true"
- width="280"/>
- </panel>
- <text
- follows="left|top"
- height="15"
- layout="topleft"
- link="true"
- left="10"
- name="partner_edit_link"
- value="[[URL] Edit]"
- width="70" />
- </panel>
- </panel>
- </scroll_container>
- <panel
- follows="bottom|left|right"
- height="28"
- left="0"
- name="profile_me_buttons_panel"
- top_pad="0"
- width="313">
-
- <layout_stack
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- name="bottom_panel_ls"
- left="7"
- orientation="horizontal"
- top_pad="0"
- width="295">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- name="save_changes_btn_lp"
- top="0"
- auto_resize="true"
- width="153">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save Changes"
- layout="topleft"
- left="1"
- name="save_btn"
- top="0"
- width="152" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- top="0"
- auto_resize="true"
- width="154">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- left="1"
- name="cancel_btn"
- top="0"
- width="153" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index e34335a2af..5eafb5cdf1 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -95,6 +95,7 @@ Hover your mouse over the options for more help.
layout="topleft"
max_length="511"
name="charter"
+ parse_urls="true"
top="105"
right="-4"
bg_readonly_color="DkGray2"
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..b72af7221e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="group_list_item"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+>
+ <icon
+ name="hovered_icon"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+ image_name="ListItem_Over"
+ visible="false"
+ />
+ <icon
+ name="selected_icon"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+ image_name="ListItem_Select"
+ visible="false"
+ />
+ <group_icon
+ name="group_icon"
+ top="2"
+ left="5"
+ height="14"
+ width="14"
+ image_name="Generic_Group"
+ mouse_opaque="true"
+ use_draw_context_alpha="false"
+ />
+ <text
+ name="group_name"
+ value="Unknown"
+ top="2"
+ left_pad="5"
+ right="-2"
+ height="16"
+ follows="left|right"
+ layout="topleft"
+ parse_urls="false"
+ text_color="ScrollUnselectedColor"
+ use_ellipses="true"
+ />
+ <button
+ name="visibility_hide_btn"
+ tool_tip="Hide group on my profile"
+ top_delta="-3"
+ left_pad="3"
+ right="-53"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Profile_Group_Visibility_Off_Pressed"
+ image_unselected="Profile_Group_Visibility_Off"
+ tab_stop="false"
+ visible="false"
+ />
+ <button
+ name="visibility_show_btn"
+ tool_tip="Show group on my profile"
+ top_delta="0"
+ right_delta="0"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Profile_Group_Visibility_On_Pressed"
+ image_unselected="Profile_Group_Visibility_On"
+ tab_stop="false"
+ visible="false"
+ />
+ <button
+ name="info_btn"
+ tool_tip="More info"
+ top_delta="2"
+ left_pad="3"
+ right="-30"
+ height="16"
+ width="16"
+ follows="right"
+ image_pressed="Info_Press"
+ image_unselected="Info_Over"
+ tab_stop="false"
+ />
+ <!--*TODO: Should only appear on rollover-->
+ <button
+ name="profile_btn"
+ tool_tip="View profile"
+ top_delta="-2"
+ left_pad="5"
+ right="-3"
+ height="20"
+ width="20"
+ follows="right"
+ layout="topleft"
+ image_overlay="Web_Profile_Off"
+ tab_stop="false"
+ />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index ade004f9d0..3aba80909a 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -145,7 +145,7 @@
follows="left|top"
font="SansSerifMedium"
text_color="EmphasisColor"
- height="16"
+ height="24"
left="408"
bottom_delta="0"
label="Remember password"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index 5568ccb792..d36c83d292 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -98,7 +98,7 @@
auto_resize="false"
follows="left|right|top"
name="widget_container"
- width="532"
+ width="730"
left="0"
top="0"
height="80">
@@ -106,7 +106,7 @@
allow_text_entry="true"
follows="left|bottom"
height="32"
- left="2"
+ left="42"
label="Username"
combo_editor.font="SansSerifLarge"
max_chars="128"
@@ -126,7 +126,7 @@
follows="left|top"
width="200"
height="32"
- left="220"
+ left="262"
max_length_chars="16"
name="password_edit"
label="Password"
@@ -145,42 +145,58 @@
label_color="White"
font="SansSerifLarge"
name="connect_btn"
- left="432"
- width="100"
+ left_pad="15"
+ width="120"
height="32"
top="0" />
+ <text
+ follows="left|top"
+ font="SansSerifLarge"
+ font.style="BOLD"
+ text_color="EmphasisColor"
+ height="34"
+ name="sign_up_text"
+ left_pad="10"
+ top="0"
+ width="200"
+ valign="center">
+ Sign up
+ </text>
<check_box
- control_name="RememberPassword"
follows="left|top"
font="SansSerifLarge"
- left="0"
+ left="42"
top="32"
height="24"
label="Remember me"
+ word_wrap="down"
check_button.bottom="3"
- name="remember_check"
- width="145" />
- <text
+ name="remember_name"
+ tool_tip="Already remembered user can be forgotten from Me &gt; Preferences &gt; Advanced &gt; Remembered Usernames."
+ width="198" />
+ <check_box
+ control_name="RememberPassword"
follows="left|top"
font="SansSerifLarge"
text_color="EmphasisColor"
- height="16"
- name="forgot_password_text"
- left="219"
- top="34"
- width="200">
- Forgotten password
- </text>
+ height="24"
+ left="262"
+ bottom_delta="0"
+ label="Remember password"
+ word_wrap="down"
+ check_button.bottom="3"
+ name="remember_password"
+ width="198" />
<text
follows="left|top"
font="SansSerifLarge"
text_color="EmphasisColor"
height="16"
- name="sign_up_text"
- left="432"
+ name="forgot_password_text"
+ left="492"
top="34"
width="200">
- Sign up
+ Forgotten password
</text>
</layout_panel>
<layout_panel
@@ -216,24 +232,17 @@
auto_resize="false"
follows="left|right|top"
name="images_container"
- width="832"
+ width="675"
left="0"
top="0"
height="500">
<icon
- height="400"
- width="400"
- image_name="first_login_image_left"
+ height="450"
+ width="675"
+ image_name="first_login_image"
left="0"
name="image_left"
top="0" />
- <icon
- height="400"
- width="400"
- image_name="first_login_image_right"
- left_pad="32"
- name="image_right"
- top="0" />
</layout_panel>
<layout_panel
height="100"
diff --git a/indra/newview/skins/default/xui/en/panel_me.xml b/indra/newview/skins/default/xui/en/panel_me.xml
deleted file mode 100644
index 23e7814cad..0000000000
--- a/indra/newview/skins/default/xui/en/panel_me.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- border="false"
- follows="all"
- height="570"
- label="My Profile"
- layout="topleft"
- left="0"
- name="panel_me"
- top="0"
- width="333">
- <panel
- class="panel_picks"
- filename="panel_picks.xml"
- label="MY PICKS"
- help_topic="panel_my_picks_tab"
- name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 1c9aa1eb83..b44c19810b 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -4,7 +4,6 @@
background_visible="true"
bg_opaque_color="MouseGray"
follows="left|top|right"
- focus_root="true"
height="34"
layout="topleft"
name="navigation_bar"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
deleted file mode 100644
index 99c47eb825..0000000000
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- follows="all"
- height="570"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_pick_info"
- help_topic="profile_pick_info"
- top="0"
- width="333">
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- follows="top|left|right"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="2"
- value="Pick Info"
- use_ellipses="true"
- width="275" />
- <scroll_container
- color="DkGray2"
- opaque="true"
- follows="all"
- height="503"
- layout="topleft"
- left="8"
- top_pad="10"
- name="profile_scroll"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="400"
- left="0"
- width="285">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- enabled="false"
- follows="left|top|right"
- height="197"
- layout="topleft"
- left="11"
- name="pick_snapshot"
- top="10"
- width="272" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="35"
- width="280"
- layout="topleft"
- font="SansSerifBig"
- font.style="BOLD"
- left="10"
- top_pad="10"
- name="pick_name"
- read_only="true"
- text_color="white"
- v_pad="0"
- value="[name]"
- use_ellipses="true" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="25"
- layout="topleft"
- left="10"
- name="pick_location"
- read_only="true"
- width="280"
- word_wrap="true"
- v_pad="0"
- value="[loading...]" />
- <text_editor
- bg_readonly_color="DkGray2"
- follows="all"
- height="100"
- width="280"
- parse_urls="true"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="1023"
- name="pick_desc"
- read_only="true"
- text_readonly_color="white"
- value="[description]"
- wrap="true" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- layout="topleft"
- top_pad="5"
- left="8"
- name="buttons">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="layout_stack1"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="312">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="layout_panel1"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- top="0"
- width="101" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- auto_resize="true"
- width="100">
- <button
- follows="bottom|left|right"
- height="23"
- label="Map"
- layout="topleft"
- name="show_on_map_btn"
- top_pad="0"
- width="100" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="edit_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- name="edit_btn"
- top_pad="0"
- width="101" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
deleted file mode 100644
index 8def96cada..0000000000
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ /dev/null
@@ -1,227 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- follows="all"
- height="571"
- label="Picks"
- layout="topleft"
- left="8"
- name="panel_picks"
- top_pad="0"
- width="313">
- <string
- name="no_picks"
- value="No Picks" />
- <string
- name="no_classifieds"
- value="No Classifieds" />
- <text
- type="string"
- follows="all"
- height="535"
- layout="topleft"
- left="6"
- name="picks_panel_text"
- wrap="true"
- top="10"
- width="313"/>
- <accordion
- fit_parent="true"
- follows="all"
- height="514"
- layout="topleft"
- left="0"
- name="accordion"
- top="0"
- single_expansion="true"
- width="313">
- <accordion_tab
- layout="topleft"
- height="235"
- min_height="150"
- name="tab_picks"
- title="Picks"
- visible="false">
- <flat_list_view
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="0"
- name="picks_list"
- opaque="true"
- top="0"
- width="313" />
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- height="235"
- name="tab_classifieds"
- title="Classifieds"
- visible="false">
- <flat_list_view
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="0"
- name="classifieds_list"
- opaque="true"
- top="0"
- width="313" />
- </accordion_tab>
- </accordion>
- <panel
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- bevel_style="none"
- enabled="false"
- follows="bottom|left|right"
- left="1"
- height="27"
- label="bottom_panel"
- layout="topleft"
- name="edit_panel"
- top_pad="0"
- width="312">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- name="edit_panel_ls"
- left="10"
- orientation="horizontal"
- top_pad="0"
- width="293">
-
- <layout_panel
- follows="bottom|left"
- height="18"
- layout="bottomleft"
- left="0"
- name="gear_menu_btn"
- auto_resize="true"
- width="51">
- <button
- follows="bottom|left"
- height="18"
- image_disabled="AddItem_Disabled"
- image_selected="AddItem_Press"
- image_unselected="AddItem_Off"
- layout="topleft"
- left="0"
- name="new_btn"
- tool_tip="Create a new pick or classified at the current location"
- top="0"
- width="18" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|right"
- height="18"
- layout="bottomleft"
- name="trash_btn_lp"
- auto_resize="true"
- width="18">
- <button
- follows="bottom|right"
- height="18"
- image_disabled="TrashItem_Disabled"
- image_selected="TrashItem_Press"
- image_unselected="TrashItem_Off"
- layout="topleft"
- name="trash_btn"
- top="0"
- width="18" />
- </layout_panel>
-
- </layout_stack>
- </panel>
-
- <panel
- bg_opaque_color="DkGray"
- background_visible="true"
- background_opaque="true"
- follows="bottom|left|right"
- layout="topleft"
- left="0"
- height="30"
- name="buttons_cucks"
- top_pad="0"
- width="313">
-
- <layout_stack
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- left="2"
- name="buttons_cucks_ls"
- orientation="horizontal"
- top="0"
- width="313">
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- left="0"
- name="info_btn_lp"
- auto_resize="true"
- top="0"
- width="95">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Info"
- layout="topleft"
- name="info_btn"
- tab_stop="false"
- tool_tip="Show pick information"
- width="95" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="bottomleft"
- left_pad="2"
- name="teleport_btn_lp"
- auto_resize="true"
- width="117">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- tab_stop="false"
- tool_tip="Teleport to the corresponding area"
- width="117" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="bottomleft"
- name="show_on_map_btn_lp"
- auto_resize="true"
- left_pad="2"
- width="90">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Map"
- layout="topleft"
- name="show_on_map_btn"
- tab_stop="false"
- tool_tip="Show the corresponding area on the World Map"
- width="88" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 5aff7a5127..38d364cf9a 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -231,34 +231,6 @@
m
</text>
- <check_box
- control_name="WindLightUseAtmosShaders"
- height="16"
- initial_value="true"
- label="Atmospheric shaders"
- layout="topleft"
- left="30"
- name="WindLightUseAtmosShaders"
- top_delta="24"
- width="280">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
- control_name="RenderDeferred"
- height="16"
- initial_value="true"
- label="Advanced Lighting Model"
- layout="topleft"
- left="30"
- name="UseLightShaders"
- top_delta="24"
- width="256">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
<slider
control_name="IndirectMaxComplexity"
tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
@@ -274,7 +246,7 @@
max_val="101"
name="IndirectMaxComplexity"
show_text="false"
- top_delta="60"
+ top_delta="36"
width="300">
<slider.commit_callback
function="Pref.UpdateIndirectMaxComplexity"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
index 67eff2b762..08ff3d4d53 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
@@ -126,6 +126,31 @@
type="string"
length="1"
follows="left|top"
+ height="12"
+ layout="topleft"
+ left="37"
+ name="title_pbr"
+ top_pad="7"
+ width="100">
+ PBR Materials
+ </text>
+ <text
+ type="string"
+ use_ellipses="true"
+ follows="left|top"
+ height="27"
+ layout="topleft"
+ font.style="BOLD"
+ left="37"
+ name="upload_pbr"
+ top_pad="5"
+ width="370"
+ word_wrap="true"/>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
height="30"
layout="topleft"
font.style="ITALIC"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_classified.xml b/indra/newview/skins/default/xui/en/panel_profile_classified.xml
new file mode 100644
index 0000000000..c9e8b242d4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_classified.xml
@@ -0,0 +1,830 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_classified"
+ top="0"
+ left="0"
+ height="420"
+ width="315"
+ follows="all"
+ layout="topleft"
+ help_topic="panel_profile_classified"
+ min_height="250"
+>
+ <panel.string
+ name="type_mature"
+ >
+ Moderate
+ </panel.string>
+ <panel.string
+ name="type_pg"
+ >
+ General Content
+ </panel.string>
+ <panel.string
+ name="l$_price"
+ >
+ L$[PRICE]
+ </panel.string>
+ <panel.string
+ name="click_through_text_fmt"
+ >
+ [TELEPORT] teleport, [MAP] map, [PROFILE] profile
+ </panel.string>
+ <panel.string
+ name="date_fmt"
+ >
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string
+ name="auto_renew_on"
+ >
+ Enabled
+ </panel.string>
+ <panel.string
+ name="auto_renew_off"
+ >
+ Disabled
+ </panel.string>
+ <panel.string
+ name="location_notice"
+ >
+ (will update after save)
+ </panel.string>
+ <string
+ name="publish_label"
+ >
+ Publish
+ </string>
+ <string
+ name="save_label"
+ >
+ Save
+ </string>
+
+ <layout_stack
+ name="main_classifieds_stack"
+ top="0"
+ bottom="-1"
+ left="0"
+ width="310"
+ follows="all"
+ layout="topleft"
+ orientation="vertical"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ width="310"
+ height="300"
+ layout="topleft"
+ name="scroll_layout_panel"
+ auto_resize="true">
+ <scroll_container
+ name="profile_scroll"
+ top="0"
+ left="0"
+ height="300"
+ width="310"
+ follows="all"
+ layout="topleft"
+ color="DkGray2"
+ opaque="true"
+ reserve_scroll_corner="false"
+ >
+ <panel
+ name="info_scroll_content_panel"
+ top="0"
+ left="0"
+ height="562"
+ width="280"
+ follows="left|top|right"
+ layout="topleft"
+ background_visible="false"
+ min_height="200"
+ >
+ <texture_picker
+ name="classified_snapshot"
+ enabled="false"
+ top="0"
+ left="10"
+ height="161"
+ width="260"
+ follows="left|top"
+ layout="topleft"
+ fallback_image="default_land_picture.j2c"
+ />
+ <icon
+ name="edit_icon"
+ label=""
+ tool_tip="Click to select an image"
+ top="0"
+ left="0"
+ height="161"
+ width="260"
+ layout="topleft"
+ follows="left|top"
+ image_name="spacer24.tga"
+ visible="false"
+ />
+ <layout_stack
+ name="info_panel"
+ top="145"
+ left="0"
+ height="375"
+ width="310"
+ follows="all"
+ layout="topleft"
+ visible="true"
+ animate="false"
+ orientation="vertical"
+ >
+ <layout_panel
+ name="main_info_panel"
+ top="0"
+ left="0"
+ height="160"
+ width="280"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text_editor
+ name="classified_name"
+ top="0"
+ left="10"
+ height="35"
+ width="270"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ font="SansSerifBig"
+ font.style="BOLD"
+ h_pad="0"
+ read_only="true"
+ text_color="white"
+ use_ellipses="true"
+ v_pad="0"
+ >
+ [name]
+ </text_editor>
+ <text
+ name="classified_location_label"
+ value="Location:"
+ top_pad="-2"
+ left="10"
+ height="10"
+ width="250"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="classified_location"
+ value="[loading...]"
+ top_pad="5"
+ left="10"
+ height="30"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ read_only="true"
+ v_pad="0"
+ word_wrap="true"
+ />
+ <text
+ name="content_type_label"
+ value="Content Type:"
+ top_pad="10"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <icon
+ name="content_type_moderate"
+ top_pad="-11"
+ left_pad="0"
+ height="16"
+ width="18"
+ follows="top|left"
+ layout="topleft"
+ image_name="Parcel_M_Light"
+ />
+ <icon
+ name="content_type_general"
+ top_delta="0"
+ left_delta="0"
+ height="16"
+ width="18"
+ follows="top|left"
+ layout="topleft"
+ image_name="Parcel_PG_Light"
+ />
+ <text_editor
+ name="content_type"
+ value="[content type]"
+ top_delta="1"
+ left_pad="2"
+ height="18"
+ width="130"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="category_label"
+ value="Category:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="category"
+ value="[category]"
+ top_pad="-10"
+ left_pad="0"
+ height="18"
+ width="150"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ parse_urls="true"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="creation_date_label"
+ value="Creation date:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="creation_date"
+ value="[date]"
+ tool_tip="Creation date"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="price_for_listing_label"
+ value="Price for listing:"
+ top_pad="5"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="price_for_listing"
+ tool_tip="Price for listing."
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="105"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ >
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel
+ name="clickthrough_layout_panel"
+ top="0"
+ left="0"
+ height="16"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text
+ name="click_through_label"
+ value="Clicks:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="click_through_text"
+ value="[clicks]"
+ tool_tip="Click through data"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ />
+ </layout_panel>
+ <layout_panel
+ name="auto_renew_layout_panel"
+ top="0"
+ left="0"
+ height="16"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text
+ name="auto_renew_label"
+ value="Auto renew:"
+ top="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text
+ name="auto_renew"
+ value="Enabled"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="top|left"
+ layout="topleft"
+ />
+ </layout_panel>
+ <layout_panel
+ name="descr_layout_panel"
+ top="0"
+ left="0"
+ height="220"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="true"
+ >
+ <text
+ name="classified_desc_label"
+ value="Description:"
+ top="0"
+ left="10"
+ height="10"
+ width="250"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="classified_desc"
+ trusted_content="false"
+ value="[description]"
+ top_pad="7"
+ left="10"
+ height="200"
+ width="280"
+ follows="all"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ max_length="1023"
+ parse_urls="true"
+ read_only="true"
+ v_pad="0"
+ word_wrap="true"
+ />
+ </layout_panel>
+ </layout_stack>
+ <panel
+ name="edit_panel"
+ top="145"
+ left="0"
+ height="420"
+ width="320"
+ follows="left|top|right"
+ layout="topleft"
+ visible="false"
+ >
+ <text
+ name="Name:"
+ top="0"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Title:
+ </text>
+ <line_editor
+ name="classified_name_edit"
+ top_pad="2"
+ left="10"
+ height="20"
+ width="273"
+ follows="left|top|right"
+ layout="topleft"
+ font="SansSerif"
+ max_length_bytes="30"
+ prevalidate_callback="ascii"
+ commit_on_focus_lost="false"
+ text_color="black"
+ />
+ <text
+ name="description_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Description:
+ </text>
+ <text_editor
+ name="classified_desc_edit"
+ top_pad="2"
+ left="10"
+ height="100"
+ width="273"
+ follows="left|top|right"
+ layout="topleft"
+ max_length="256"
+ text_color="black"
+ word_wrap="true"
+ />
+ <text
+ name="location_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Location:
+ </text>
+ <text
+ name="classified_location_edit"
+ top_pad="2"
+ left="10"
+ right="-10"
+ height="30"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ length="1"
+ type="string"
+ word_wrap="true"
+ >
+ loading...
+ </text>
+ <button
+ name="set_to_curr_location_btn"
+ label="Set to Current Location"
+ top_pad="5"
+ left="10"
+ height="23"
+ width="200"
+ follows="left|top"
+ layout="topleft"
+ />
+ <text
+ name="category_label"
+ value="Category:"
+ top_pad="10"
+ left="10"
+ height="10"
+ width="120"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <combo_box
+ name="category_edit"
+ label=""
+ top_delta="-3"
+ left_pad="0"
+ height="23"
+ width="156"
+ follows="left|top"
+ />
+ <text
+ name="content_type_label"
+ value="Content type:"
+ top_pad="15"
+ left="10"
+ height="10"
+ width="120"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <icons_combo_box
+ name="content_type_edit"
+ label="General Content"
+ top_delta="-3"
+ left_pad="0"
+ height="23"
+ width="156"
+ follows="left|top"
+ layout="topleft"
+ >
+ <icons_combo_box.drop_down_button
+ image_overlay="Parcel_PG_Light"
+ image_overlay_alignment="left"
+ imgoverlay_label_space="3"
+ pad_left="3"
+ />
+ <icons_combo_box.item
+ name="mature_ci"
+ label="Moderate Content"
+ value="Mature"
+ >
+ <item.columns
+ value="Parcel_M_Light"
+ width="20"
+ halign="center"
+ type="icon"
+ />
+ </icons_combo_box.item>
+ <icons_combo_box.item
+ name="pg_ci"
+ label="General Content"
+ value="PG"
+ >
+ <item.columns
+ value="Parcel_PG_Light"
+ width="20"
+ halign="center"
+ type="icon"
+ />
+ </icons_combo_box.item>
+ </icons_combo_box>
+ <check_box
+ name="auto_renew_edit"
+ label="Auto renew each week"
+ top_pad="10"
+ left="10"
+ height="16"
+ width="250"
+ layout="topleft"
+ />
+ </panel>
+ </panel>
+ </scroll_container>
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ width="310"
+ height="25"
+ layout="topleft"
+ name="util_buttons_lp"
+ auto_resize="true">
+ <layout_stack
+ name="util_buttons_stack"
+ bottom="-1"
+ left="1"
+ right="-1"
+ height="25"
+ follows="left|bottom|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_left"
+ auto_resize="true"
+ user_resize="false"
+ width="1"/>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="teleport_btn_lp"
+ auto_resize="false"
+ top="0"
+ width="85">
+ <button
+ name="teleport_btn"
+ label="Teleport"
+ top="0"
+ left="0"
+ height="23"
+ max_width="101"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="bottomleft"
+ left_pad="2"
+ name="map_btn_lp"
+ auto_resize="false"
+ max_width="101"
+ width="85">
+ <button
+ name="show_on_map_btn"
+ label="Map"
+ top="0"
+ left="0"
+ height="23"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="bottomleft"
+ left_pad="2"
+ name="edit_btn_lp"
+ auto_resize="false"
+ max_width="101"
+ width="85">
+ <button
+ name="edit_btn"
+ label="Edit"
+ top="0"
+ left="0"
+ height="23"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ width="310"
+ height="41"
+ layout="topleft"
+ name="publish_layout_panel"
+ auto_resize="false">
+ <view_border
+ bevel_style="none"
+ height="0"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ name="publish_emphasis_border"
+ top="5"
+ width="310"/>
+ <layout_stack
+ name="publish_stack"
+ left="1"
+ right="-1"
+ top="11"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="pbl_resizer_left"
+ auto_resize="true"
+ user_resize="false"
+ width="1"/>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_btn_lp"
+ auto_resize="false"
+ width="134">
+ <button
+ name="save_changes_btn"
+ label="[LABEL]"
+ top="0"
+ left="0"
+ left_pad="5"
+ height="23"
+ width="134"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="cancel_btn_lp"
+ auto_resize="false"
+ width="134">
+ <button
+ name="cancel_btn"
+ label="Cancel"
+ top="0"
+ left="0"
+ height="23"
+ width="134"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="pbl_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..2b2f60e0c2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_classifieds"
+ label="Classified"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="no_classifieds"
+ value="No Classifieds"
+ />
+
+ <layout_stack
+ name="main_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <button
+ name="new_btn"
+ label="New..."
+ tool_tip="Create a new classified at the current location"
+ enabled="false"
+ top="25"
+ left="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ />
+ <button
+ name="delete_btn"
+ label="Delete..."
+ tool_tip="Delete currently selected classified"
+ enabled="false"
+ left_pad="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ />
+ </layout_panel>
+ <layout_panel
+ name="main_body"
+ follows="all"
+ layout="topleft"
+ height="430"
+ auto_resize="true"
+ user_resize="false">
+ <tab_container
+ name="tab_classifieds"
+ top="0"
+ bottom="-1"
+ left="4"
+ right="-4"
+ follows="all"
+ layout="topleft"
+ halign="left"
+ tab_position="left"
+ tab_width="150"
+ use_ellipses="true"
+ />
+
+ <layout_stack
+ name="indicator_stack"
+ top="220"
+ left="0"
+ right="-1"
+ height="28"
+ follows="top|left|right"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ name="indicator_spacer_left"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ width="25"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ top="1"
+ left="1"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="indicator_spacer_right"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ </layout_stack>
+ <text
+ name="classifieds_panel_text"
+ top="250"
+ left="110"
+ right="-110"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ mouse_opaque="false"
+ wrap="true"
+ >
+ Loading...
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..ca1e405a62
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_firstlife"
+ label="Profile"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <loading_indicator
+ name="progress_indicator"
+ top="5"
+ right="-10"
+ height="23"
+ width="23"
+ follows="top|right"
+ layout="topleft"
+ visible="false"
+ />
+ <icon
+ name="real_world_pic"
+ image_name="Generic_Person_Large"
+ follows="top|left"
+ layout="topleft"
+ top="10"
+ left="8"
+ height="160"
+ width="160"/>
+ <loading_indicator
+ name="image_upload_indicator"
+ top="79"
+ left="77"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"/>
+ <button
+ name="fl_upload_image"
+ label="Upload Photo"
+ top="102"
+ left="175"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="fl_change_image"
+ label="Change Photo"
+ top_pad="5"
+ left="175"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="fl_remove_image"
+ label="Remove Photo"
+ top_pad="5"
+ left_delta="0"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <text_editor
+ name="fl_description_edit"
+ trusted_content="false"
+ enabled="false"
+ top="180"
+ left="6"
+ right="-6"
+ height="224"
+ follows="all"
+ layout="topleft"
+ bg_readonly_color="Transparent"
+ border_visible="true"
+ max_length="65000"
+ parse_urls="true"
+ word_wrap="true"
+ />
+ <button
+ name="fl_save_changes"
+ label="Save"
+ top_pad="5"
+ right="-108"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="right|bottom"
+ layout="topleft"/>
+ <button
+ name="fl_discard_changes"
+ label="Discard"
+ top_delta="0"
+ right="-4"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="right|bottom"
+ layout="topleft"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_notes.xml
new file mode 100644
index 0000000000..16e7365042
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_notes.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_notes"
+ label="Notes &amp; Privacy"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <loading_indicator
+ name="progress_indicator"
+ top="3"
+ right="-10"
+ height="23"
+ width="23"
+ follows="top|right"
+ layout="topleft"
+ visible="false"
+ />
+ <text
+ name="status_message"
+ value="Make notes about this person here. No one else can see your notes."
+ top="6"
+ left="6"
+ right="-6"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ font.style="BOLD"
+ />
+ <text_editor
+ name="notes_edit"
+ enabled="false"
+ top="28"
+ left="6"
+ right="-6"
+ bottom="-26"
+ follows="all"
+ layout="topleft"
+ max_length="65530"
+ word_wrap="true"
+ />
+ <button
+ name="notes_save_changes"
+ label="Save"
+ bottom="-1"
+ right="-108"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="bottom|right"
+ layout="topleft"/>
+ <button
+ name="notes_discard_changes"
+ label="Discard"
+ bottom="-1"
+ right="-4"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="bottom|right"
+ layout="topleft"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml
new file mode 100644
index 0000000000..3e91640093
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_pick_info"
+ top="0"
+ left="0"
+ height="360"
+ width="310"
+ follows="all"
+ layout="topleft"
+ help_topic="profile_pick_info"
+>
+ <panel.string
+ name="location_notice"
+ >
+ (will update after save)
+ </panel.string>
+
+ <layout_stack
+ name="main_pick_stack"
+ left="1"
+ right="-1"
+ top="0"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ orientation="vertical"
+ animate="false">
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="main_pick_lp"
+ auto_resize="true"
+ height="314">
+ <texture_picker
+ name="pick_snapshot"
+ top="10"
+ left="10"
+ height="161"
+ width="260"
+ follows="left|top"
+ layout="topleft"
+ fallback_image="default_land_picture.j2c"
+ />
+ <text
+ name="title_label"
+ top_pad="-15"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Title:
+ </text>
+ <line_editor
+ name="pick_name"
+ enabled="false"
+ top_pad="2"
+ left="10"
+ height="20"
+ width="290"
+ follows="left|right|top"
+ layout="topleft"
+ />
+ <text
+ name="description_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Description:
+ </text>
+ <text_editor
+ name="pick_desc"
+ trusted_content="false"
+ always_show_icons="true"
+ enabled="false"
+ top_pad="2"
+ left="10"
+ height="45"
+ width="290"
+ follows="all"
+ layout="topleft"
+ allow_html="true"
+ border_visible="true"
+ h_pad="4"
+ max_length="1023"
+ v_pad="3"
+ word_wrap="true"
+ />
+ <text
+ name="location_label"
+ bottom="-25"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|right|bottom"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Location:
+ </text>
+ <line_editor
+ name="pick_location"
+ enabled="false"
+ bottom="-1"
+ left="10"
+ height="23"
+ width="290"
+ follows="left|right|bottom"
+ layout="topleft"
+ length="1"
+ type="string"
+ >
+ Loading...
+ </line_editor>
+ </layout_panel>
+
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ name="save_changes_lp"
+ auto_resize="false"
+ height="25">
+ <layout_stack
+ name="save_changes_stack"
+ left="1"
+ right="-1"
+ top="0"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false">
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="map_btn_lp"
+ auto_resize="false"
+ width="100">
+ <button
+ name="show_on_map_btn"
+ label="Show on Map"
+ left="0"
+ top="0"
+ height="23"
+ width="100"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="tp_btn_lp"
+ auto_resize="false"
+ width="100">
+ <button
+ name="teleport_btn"
+ label="Teleport"
+ left="0"
+ top="0"
+ height="23"
+ width="100"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ name="save_changes_lp"
+ auto_resize="false"
+ height="41">
+ <view_border
+ bevel_style="none"
+ height="0"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ name="save_emphasis_border"
+ top="5"
+ width="310"/>
+ <layout_stack
+ name="save_changes_stack"
+ left="1"
+ right="-1"
+ top="11"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false">
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="create_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="create_changes_btn"
+ label="Create Pick"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="save_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="save_changes_btn"
+ label="Save Pick"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="cancel_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="cancel_changes_btn"
+ label="Cancel"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_picks.xml
new file mode 100644
index 0000000000..44d5c448c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_picks.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_picks"
+ label="Picks"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="no_picks"
+ value="No Picks"
+ />
+
+ <layout_stack
+ name="main_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <text
+ name="header_text"
+ top="5"
+ left="5"
+ right="-5"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ >
+ Tell everyone about your favorite places in Second Life.
+ </text>
+ <button
+ name="new_btn"
+ label="New..."
+ tool_tip="Create a new pick at the current location"
+ enabled="false"
+ top_pad="4"
+ left="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="false"
+ />
+ <button
+ name="delete_btn"
+ label="Delete..."
+ tool_tip="Delete currently selected pick"
+ enabled="false"
+ left_pad="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="main_body"
+ follows="all"
+ layout="topleft"
+ height="430"
+ auto_resize="true"
+ user_resize="false">
+ <tab_container
+ name="tab_picks"
+ top="0"
+ bottom="-5"
+ left="4"
+ right="-4"
+ tab_width="150"
+ follows="all"
+ layout="topleft"
+ halign="left"
+ tab_position="left"
+ use_ellipses="true"
+ />
+
+ <layout_stack
+ name="indicator_stack"
+ top="220"
+ left="0"
+ right="-1"
+ height="28"
+ follows="top|left|right"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ name="indicator_spacer_left"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ width="25"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ top="1"
+ left="1"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="indicator_spacer_right"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ </layout_stack>
+ <text
+ name="picks_panel_text"
+ top="250"
+ left="100"
+ right="-100"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ mouse_opaque="false"
+ wrap="true"
+ >
+ Loading...
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..551b477876
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
@@ -0,0 +1,549 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile"
+ label="Profile"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="date_format"
+ value="SL birthdate: [mth,datetime,slt] [day,datetime,slt], [year,datetime,slt]" />
+ <string
+ name="age_format"
+ value="[AGE]" />
+ <string
+ name="partner_text"
+ value="Partner: [LINK]" />
+ <string
+ name="CaptionTextAcctInfo">
+Account: [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+
+ <layout_stack
+ name="image_stack"
+ top="8"
+ left="6"
+ bottom="-1"
+ width="160"
+ border_size="0"
+ follows="left|top|bottom"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="image_panel"
+ follows="all"
+ layout="topleft"
+ width="160"
+ height="160"
+ auto_resize="false"
+ user_resize="false">
+
+ <icon
+ name="2nd_life_pic"
+ image_name="Generic_Person_Large"
+ layout="topleft"
+ follows="all"
+ interactable="true"
+ top="0"
+ left="2"
+ bottom="-1"
+ right="-1"/>
+
+ <loading_indicator
+ name="image_upload_indicator"
+ top="69"
+ left="69"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"/>
+ </layout_panel>
+
+ <layout_panel
+ name="basics_panel"
+ follows="all"
+ layout="topleft"
+ height="54"
+ auto_resize="false"
+ user_resize="false"
+ >
+ <line_editor
+ name="user_name"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top="4"
+ left="3"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <line_editor
+ name="sl_birth_date"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top_pad="0"
+ left_delta="0"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <line_editor
+ name="user_age"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top_pad="0"
+ left_delta="0"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ </layout_panel>
+ <layout_panel
+ name="partner_layout"
+ follows="all"
+ layout="topleft"
+ height="30"
+ auto_resize="false"
+ user_resize="false"
+ visible="true">
+ <text
+ type="string"
+ name="partner_link"
+ value="Partner: (loading...)"
+ top="0"
+ left="5"
+ right="-1"
+ height="28"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ use_ellipses="true"
+ word_wrap="true"
+ visible="true"/>
+ </layout_panel>
+
+ <layout_panel
+ name="partner_spacer_layout"
+ follows="all"
+ layout="topleft"
+ height="14"
+ auto_resize="false"
+ user_resize="false"
+ visible="true">
+ </layout_panel>
+
+ <layout_panel
+ name="frind_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <text
+ name="frind_text"
+ value="You are friends"
+ text_color="ConversationFriendColor"
+ top="0"
+ left="5"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="online_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="online_icon"
+ image_name="Profile_Friend_Online"
+ layout="topleft"
+ follows="left|top"
+ top="0"
+ left="5"
+ height="10"
+ width="10"/>
+ <text
+ name="online_text"
+ value="Online"
+ top="0"
+ left="18"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="offline_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="offline_icon"
+ image_name="Profile_Friend_Offline"
+ layout="topleft"
+ follows="left|top"
+ top="0"
+ left="5"
+ height="10"
+ width="10"/>
+ <text
+ name="offline_text"
+ value="Offline"
+ top="0"
+ left="18"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="account_layout"
+ follows="all"
+ layout="topleft"
+ height="33"
+ auto_resize="false"
+ user_resize="false">
+ <text
+ name="account_info"
+ value="Account: (loading...)"
+ top="0"
+ left="5"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ word_wrap="true"/>
+ </layout_panel>
+ <layout_panel
+ name="indicator_stack"
+ follows="all"
+ layout="topleft"
+ height="33"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ left="67"
+ top="0"
+ height="23"
+ width="23"
+ follows="left|top"
+ layout="topleft"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="settings_panel"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <!-- only for self -->
+ <text
+ name="search_label"
+ value="Show my profile in search:"
+ top="1"
+ left="6"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ <combo_box
+ name="show_in_search"
+ tool_tip="Let people see you in search results"
+ left="1"
+ top="18"
+ height="23"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ enabled="false">
+ <combo_box.item
+ name="Hide"
+ label="Hide"
+ value="0" />
+ <combo_box.item
+ name="Show"
+ label="Show"
+ value="1" />
+ </combo_box>
+ </layout_panel>
+
+ <layout_panel
+ name="menu_panel"
+ follows="all"
+ layout="topleft"
+ height="55"
+ auto_resize="false"
+ user_resize="false"
+ >
+ <menu_button
+ layout="topleft"
+ follows="left|top"
+ left="1"
+ top="25"
+ height="25"
+ width="140"
+ label="Actions"
+ halign="left"
+ image_unselected="DropDown_Off"
+ image_selected="DropDown_On"
+ image_pressed="DropDown_Press"
+ image_pressed_selected="DropDown_Press"
+ image_disabled="DropDown_Disabled"
+ name="agent_actions_menu" />
+ </layout_panel>
+ </layout_stack>
+
+ <layout_stack
+ name="main_stack"
+ top="8"
+ left="168"
+ bottom="-1"
+ right="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="display_name_panel"
+ follows="all"
+ layout="topleft"
+ height="24"
+ auto_resize="false"
+ user_resize="false">
+ <line_editor
+ name="display_name"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ font="SansSerifBigLarge"
+ top="0"
+ left="6"
+ height="19"
+ right="-86"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <icon
+ tool_tip="Friend can see my online status"
+ mouse_opaque="true"
+ name="can_see_online"
+ image_name="Profile_Perm_Online_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-61"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not see my online status"
+ mouse_opaque="true"
+ name="cant_see_online"
+ image_name="Profile_Perm_Online_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-61"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can see me on map"
+ mouse_opaque="true"
+ name="can_see_on_map"
+ image_name="Profile_Perm_Find_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-30"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not see me on map"
+ mouse_opaque="true"
+ name="cant_see_on_map"
+ image_name="Profile_Perm_Find_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-30"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can edit my objects"
+ mouse_opaque="true"
+ name="can_edit_objects"
+ image_name="Profile_Perm_Objects_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-1"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not edit my objects"
+ mouse_opaque="true"
+ name="cant_edit_objects"
+ image_name="Profile_Perm_Objects_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-1"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ </layout_panel>
+
+ <layout_panel
+ name="about_panel"
+ follows="all"
+ layout="topleft"
+ height="159"
+ auto_resize="true"
+ user_resize="false">
+ <text_editor
+ name="sl_description_edit"
+ trusted_content="false"
+ always_show_icons="true"
+ commit_on_focus_lost="false"
+ enabled="false"
+ top="0"
+ left="2"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ bg_readonly_color="Transparent"
+ border_visible="true"
+ font="SansSerifSmall"
+ h_pad="2"
+ max_length="65000"
+ parse_urls="true"
+ word_wrap="true"
+ />
+ </layout_panel>
+ <layout_panel
+ name="about_buttons_panel"
+ follows="all"
+ layout="topleft"
+ height="34"
+ auto_resize="false"
+ user_resize="false">
+ <button
+ name="save_description_changes"
+ label="Save"
+ top="1"
+ right="-105"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="top|right"
+ layout="topleft"/>
+ <button
+ name="discard_description_changes"
+ label="Discard"
+ top="1"
+ right="-1"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="top|right"
+ layout="topleft"/>
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="cost_text_border"
+ top_pad="9"
+ width="492"/>
+ </layout_panel>
+
+ <layout_panel
+ name="groups_panel"
+ follows="all"
+ layout="topleft"
+ height="159"
+ auto_resize="true"
+ user_resize="false">
+ <text
+ name="group_label"
+ value="Group memberships"
+ top="1"
+ left="2"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ <group_list
+ name="group_list"
+ top="18"
+ left="2"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ border_visible="true"
+ color="ScrollBgWriteableColor"
+ for_agent="false"/>
+
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_web.xml b/indra/newview/skins/default/xui/en/panel_profile_web.xml
new file mode 100644
index 0000000000..e0cb4d3d06
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_web.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_web"
+ label="Web"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <panel.string
+ name="LoadTime"
+ value="Load Time: [TIME] seconds"
+ />
+ <web_browser
+ name="profile_html"
+ top="10"
+ bottom="-18"
+ left="10"
+ right="-10"
+ follows="all"
+ layout="topleft"
+ start_url=""
+ />
+ <text
+ name="status_text"
+ bottom="-4"
+ left="110"
+ right="-110"
+ follows="bottom|left|right"
+ layout="topleft"
+ halign="center"
+ parse_urls="false"
+ />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index 8243c2715d..2aaea04a6d 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -86,7 +86,7 @@
name="detail_texture_text"
top="110"
width="300">
- Terrain Textures (requires 512x512, 24 bit .tga files)
+ Terrain Textures (requires 1024x1024, 24 bit .tga files)
</text>
<texture_picker
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
index 6f82a0efa1..094be36b01 100644
--- a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
@@ -315,6 +315,29 @@
top_delta="20"
width="219"
can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="200">
+ Reflection Probe Ambiance:
+ </text>
+ <slider
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1"
+ name="probe_ambiance"
+ top_delta="20"
+ width="219"
+ can_edit_text="true"/>
</layout_panel>
</layout_stack>
</layout_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 9023d68ea9..b711ed0e1c 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -11,7 +11,6 @@
mouse_opaque="false"
name="status"
top="19"
- tab_stop="false"
width="1000">
<panel.string
name="packet_loss_tooltip">
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 90f32ae452..104bcb9257 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -2,7 +2,7 @@
<panel
border="false"
follows="all"
- height="420"
+ height="500"
label="Texture"
layout="topleft"
left="0"
@@ -11,6 +11,36 @@
name="Texture"
top="0"
width="295">
+ <panel.string
+ name="paste_error_face_selection_mismatch">
+ When multiple faces are copied, the target object must have the same number of faces selected.
+ </panel.string>
+ <panel.string
+ name="paste_error_object_face_count_mismatch">
+ When all faces of an object are copied, the target object must have the same number of faces.
+ </panel.string>
+ <panel.string
+ name="paste_error_inventory_not_found">
+ One or more texture not found in inventory.
+ </panel.string>
+ <panel.string
+ name="paste_options">
+ Paste options
+ </panel.string>
+
+ <menu_button
+ menu_filename="menu_copy_paste_color.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top="8"
+ name="clipboard_color_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
@@ -36,7 +66,7 @@
name="colorswatch"
tool_tip="Click to open color picker"
top="20"
- width="64" />
+ width="54" />
<text
type="string"
length="1"
@@ -84,7 +114,7 @@
left_delta="0"
name="glow"
top_pad="4"
- width="80" />
+ width="77" />
<check_box
height="19"
label="Full Bright"
@@ -93,27 +123,39 @@
name="checkbox fullbright"
top_pad="4"
width="81" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="8"
+ name="object_horizontal"
+ top_pad="4"
+ width="278" />
<combo_box
height="23"
layout="topleft"
left="10"
name="combobox matmedia"
- top_pad="5"
- width="100">
+ top_pad="17"
+ width="90">
<combo_box.item
label="Materials"
name="Materials"
value="Materials" />
<combo_box.item
+ label="PBR"
+ name="PBR"
+ value="PBR" />
+ <combo_box.item
label="Media"
name="Media"
value="Media" />
</combo_box>
<radio_group
- control_name="ComboMaterialType"
height="50"
layout="topleft"
- left_pad="20"
+ left_pad="5"
top_delta="-10"
width="150"
visible = "false"
@@ -139,7 +181,50 @@
layout="topleft"
top_pad="1"
value="2"/>
- </radio_group>
+ </radio_group>
+ <radio_group
+ height="50"
+ layout="topleft"
+ left_delta="0"
+ top_delta="0"
+ width="150"
+ visible = "false"
+ name="radio_pbr_type">
+ <radio_item
+ label="Color/emissive"
+ name="Color/emissive"
+ top="0"
+ layout="topleft"
+ height="16"
+ value="0"/>
+ <radio_item
+ label="Normal"
+ layout="topleft"
+ top_pad="1"
+ height="16"
+ name="Normal"
+ value="1"/>
+ <radio_item
+ label="Metallic/roughness"
+ name="Metallic/roughness"
+ height="16"
+ layout="topleft"
+ top_pad="1"
+ value="2"/>
+ </radio_group>
+ <menu_button
+ menu_filename="menu_copy_paste_texture.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top_delta="0"
+ name="clipboard_texture_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<check_box
control_name="SyncMaterialSettings"
follows="top|left"
@@ -150,7 +235,7 @@
left="8"
name="checkbox_sync_settings"
tool_tip="Adjust all maps repeats simultaneously"
- top_pad="-16"
+ top_pad="19"
width="160" />
<texture_picker
can_apply_immediately="true"
@@ -165,6 +250,17 @@
tool_tip="Click to choose a picture"
top_pad="5"
width="64" />
+ <texture_picker
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="PBR "
+ layout="topleft"
+ left="10"
+ name="pbr_control"
+ tool_tip="Click to choose a pbr material"
+ top_delta="0"
+ width="64" />
<text
type="string"
length="1"
@@ -498,10 +594,7 @@
top_pad="4"
tool_tip="Add Media"
label="Choose..."
- width="85">
- <button.commit_callback
- function="BuildTool.AddMedia"/>
- </button>
+ width="85"/>
<button
follows="top|left"
height="18"
@@ -511,10 +604,7 @@
tool_tip="Delete this media texture"
top_delta="0"
label="Remove"
- width="85">
- <button.commit_callback
- function="BuildTool.DeleteMedia"/>
- </button>
+ width="85"/>
<button
follows="left|top"
height="18"
@@ -771,14 +861,14 @@
top_delta="16"
width="260" />
<button
- left="10"
- top="222"
+ follows="left|top"
+ layout="topleft"
+ left="9"
+ top="204"
height="20"
label="Align"
label_selected="Align current texture layers"
- layout="topleft"
name="button align textures"
- top_delta="0"
tool_tip="Align current texture layers"
width="66" />
<web_browser
@@ -793,4 +883,4 @@
height="4"
start_url="about:blank"
decouple_texture_size="true" />
- </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index 8a3e18707f..1c9d750aa6 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -459,7 +459,7 @@
label="Price: L$"
label_width="73"
width="150"
- min_val="1"
+ min_val="0"
height="20"
max_val="999999999"
tool_tip="Object cost." />
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index acb3a720b9..9f183d137d 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -69,6 +69,7 @@ Voice Server Version: [VOICE_VERSION]
</string>
<string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string>
<string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string>
+ <string name="LocalTime">[month, datetime, local] [day, datetime, local] [year, datetime, local] [hour, datetime, local]:[min, datetime, local]:[second,datetime, local]</string>
<string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string>
<string name="BuildConfiguration">Build Configuration</string>
@@ -111,7 +112,7 @@ Voice Server Version: [VOICE_VERSION]
<string name="CertAllocationFailure">Failed to allocate openssl memory for certificate.</string>
<string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string>
- <string name="LoginFailed">Login failed.</string>
+ <string name="LoginFailedHeader">Login failed.</string>
<string name="Quit">Quit</string>
<string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string>
@@ -125,6 +126,8 @@ http://secondlife.com/download
For more information, see our FAQ below:
http://secondlife.com/viewer-access-faq</string>
+ <string name="LoginFailed">Grid emergency login failure.
+If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginIntermediateOptionalUpdateAvailable">Optional viewer update available: [VERSION]</string>
<string name="LoginFailedRequiredUpdate">Required viewer update: [VERSION]</string>
<string name="LoginFailedAlreadyLoggedIn">This agent is already logged in.
@@ -152,15 +155,18 @@ People with free accounts will not be able to access Second Life during this tim
<string name="LoginFailedComputerProhibited">Second Life cannot be accessed from this computer.
If you feel this is an error, please contact
support@secondlife.com.</string>
+ <!--'Pacific time' placeholder for [TIME] in case time from server can't be decoded-->
+ <string name="PacificTime">Pacific Time</string>
<string name="LoginFailedAcountSuspended">Your account is not accessible until
-[TIME] Pacific Time.</string>
+[TIME].
+If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginFailedAccountDisabled">We are unable to complete your request at this time.
Please contact Second Life support for assistance at http://support.secondlife.com.</string>
<string name="LoginFailedTransformError">Data inconsistency found during login.
Please contact support@secondlife.com.</string>
<string name="LoginFailedAccountMaintenance">Your account is undergoing minor maintenance.
Your account is not accessible until
-[TIME] Pacific Time.
+[TIME].
If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginFailedPendingLogoutFault">Request for logout responded with a fault from simulator.</string>
<string name="LoginFailedPendingLogout">The system is logging you out right now.
@@ -342,8 +348,6 @@ can be attached to notecards.
<!-- Group name: text shown for LLUUID::null -->
<string name="GroupNameNone">(none)</string>
- <string name="AvalineCaller">Avaline Caller [ORDER]</string>
-
<!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. -->
<string name="AssetErrorNone">No error</string>
<string name="AssetErrorRequestFailed">Asset request: failed</string>
@@ -399,6 +403,7 @@ http://secondlife.com/support for help fixing this problem.
<string name="symbolic link">link</string>
<string name="symbolic folder link">folder link</string>
<string name="settings blob">settings</string>
+ <string name="render material">material</string>
<string name="mesh">mesh</string>
<!-- llvoavatar. Displayed in the avatar chat bubble -->
@@ -2336,6 +2341,14 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
An error occurred while opening Marketplace Listings.
If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
</string>
+ <string name="InventoryMarketplaceConnectionError">
+Marketplace Listings failed to connect.
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
+ </string>
+ <string name="InventoryMarketplaceConnectionErrorReason">
+Marketplace Listings failed to connect. Reason: [REASON]
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
+ </string>
<string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string>
<string name="InventoryMarketplaceListingsNoItemsTooltip"></string>
<string name="InventoryMarketplaceListingsNoItems">
@@ -2414,6 +2427,7 @@ If you continue to receive this message, please contact Second Life support for
<string name="Clothing" value=" Clothing," />
<string name="Gestures" value=" Gestures," />
<string name="Landmarks" value=" Landmarks," />
+ <string name="Materials" value=" Materials," />
<string name="Notecards" value=" Notecards," />
<string name="Objects" value=" Objects," />
<string name="Scripts" value=" Scripts," />
@@ -2459,6 +2473,8 @@ If you continue to receive this message, please contact Second Life support for
<string name="InvFolder Meshes">Meshes</string>
<string name="InvFolder Received Items">Received Items</string>
<string name="InvFolder Merchant Outbox">Merchant Outbox</string>
+ <string name="InvFolder Settings">Settings</string>
+ <string name="InvFolder Materials">Materials</string>
<!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
<string name="InvFolder Friends">Friends</string>
@@ -2802,10 +2818,14 @@ If you continue to receive this message, please contact Second Life support for
<string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>
<string name="ClassifiedUpdateAfterPublish">(will update after publish)</string>
- <!-- panel picks -->
- <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
- <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
- <string name="PicksClassifiedsLoadingText">Loading...</string>
+ <!-- panel picks -->
+ <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
+ <string name="NoPicksText">You haven't created any Picks. Click the New button to create a Pick.</string>
+ <string name="NoClassifiedsText">You haven't created any Classifieds. Click the New button to create a Classified.</string>
+ <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
+ <string name="NoAvatarPicksText">This person has no picks</string>
+ <string name="NoAvatarClassifiedsText">This person has no classifieds</string>
+ <string name="PicksClassifiedsLoadingText">Loading...</string>
<!-- Multi Preview Floater -->
<string name="MultiPreviewTitle">Preview</string>
@@ -3835,6 +3855,7 @@ Abuse Report</string>
<string name="New Physics">New Physics</string>
<string name="Invalid Wearable">Invalid Wearable</string>
<string name="New Gesture">New Gesture</string>
+ <string name="New Material">New Material</string>
<string name="New Script">New Script</string>
<string name="New Note">New Note</string>
<string name="New Folder">New Folder</string>
@@ -4255,6 +4276,9 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>
<string name="ExperiencePermissionShort16">Sit</string>
<string name="ExperiencePermissionShort17">Environment</string>
+ <!-- PBR Materials -->
+ <string name="Material Texture Name Header">Textures present this material: </string>
+
<!-- Conversation log messages -->
<string name="logging_calls_disabled_log_empty">
Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
diff --git a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
index 4f3c177976..87f93e8fcf 100644
--- a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Gestos" name="check_gesture"/>
<check_box label="Hitos" name="check_landmark"/>
<check_box label="Notas" name="check_notecard"/>
- <check_box label="Redes" name="check_mesh"/>
+ <check_box label="Meshs" name="check_mesh"/>
<check_box label="Objetos" name="check_object"/>
<check_box label="Scripts" name="check_script"/>
<check_box label="Sonidos" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/es/floater_preview_texture.xml b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
index b0afd44750..2543508c40 100644
--- a/indra/newview/skins/default/xui/es/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copiar al inventario
</floater.string>
- <text name="desc txt">
- Descripción:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Previsualizar la ratio de las proporciones
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta">
- <combo_item name="Unconstrained">
- Sin restricciones
- </combo_item>
- <combo_item name="1:1" tool_tip="Emblema del grupo o perfil del Mundo real">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Perfil de [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Clasificados (también en las listas de búsqueda), hitos">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Acerca del terreno">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Destacados del perfil">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Descartar" name="Discard"/>
- <button label="Guardar como" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descripción:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Previsualizar la ratio de las proporciones
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Descartar" name="Discard"/>
+ <button label="Guardar como" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_profile.xml b/indra/newview/skins/default/xui/es/floater_profile.xml
new file mode 100644
index 0000000000..c9448a0d4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Perfil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Intereses" name="panel_profile_interests"/>
+ <panel label="Destacados" name="panel_profile_picks"/>
+ <panel label="Clasificado" name="panel_profile_classifieds"/>
+ <panel label="Vida real" name="panel_profile_firstlife"/>
+ <panel label="Notas" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salvar cambios en el perfil y cerrar"/>
+ <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_snapshot.xml b/indra/newview/skins/default/xui/es/floater_snapshot.xml
index c2c996aa8a..2dfaecf3e3 100644
--- a/indra/newview/skins/default/xui/es/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/es/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Enviando el correo electrónico
</string>
+ <string name="facebook_progress_str">
+ Publicando en Facebook
+ </string>
<string name="profile_progress_str">
Publicando
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Guardando en el equipo
</string>
+ <string name="facebook_succeeded_str">
+ Imagen subida
+ </string>
<string name="profile_succeeded_str">
Imagen subida
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
¡Guardado en el equipo!
</string>
+ <string name="facebook_failed_str">
+ Error al subir la imagen a tu biografía de Facebook.
+ </string>
<string name="profile_failed_str">
Error al subir la imagen a los comentarios de tu perfil.
</string>
diff --git a/indra/newview/skins/default/xui/es/menu_name_field.xml b/indra/newview/skins/default/xui/es/menu_name_field.xml
new file mode 100644
index 0000000000..0d51fbffeb
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copiar Nombre mostrado" name="copy_display"/>
+ <menu_item_call label="Copiar Nombre de agente" name="copy_name"/>
+ <menu_item_call label="Copiar ID de agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 54707116d4..36f27bc3c6 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -2690,6 +2690,9 @@ Inténtalo seleccionando un trozo más pequeño de terreno.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_classified.xml b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
index ffad843732..09f87015cc 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Cancelar" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/es/panel_facebook_place.xml b/indra/newview/skins/default/xui/es/panel_facebook_place.xml
index 5139bd1d0b..29f6147f23 100644
--- a/indra/newview/skins/default/xui/es/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/es/panel_facebook_place.xml
@@ -3,7 +3,7 @@
<text name="place_caption_label">
Cuenta algo del lugar donde te encuentras:
</text>
- <check_box initial_value="false" label="Incluir una vista general del lugar" name="add_place_view_cb"/>
+ <check_box initial_value="false" label="Incluye una vista general del lugar" name="add_place_view_cb"/>
<button label="Publicar" name="post_place_btn"/>
<button label="Cancelar" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_group_general.xml b/indra/newview/skins/default/xui/es/panel_group_general.xml
index a17814d15d..ef919f396e 100644
--- a/indra/newview/skins/default/xui/es/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_general.xml
@@ -46,7 +46,7 @@ Deja el cursor sobre las opciones para ver más ayuda.
<check_box label="Cualquiera puede entrar" name="open_enrollement" tool_tip="Configura si se permite la entrada de nuevos miembros sin ser invitados."/>
<check_box label="Cuota de entrada" name="check_enrollment_fee" tool_tip="Configura si hay que pagar una cuota para entrar al grupo"/>
<spinner label="L$" left_delta="130" name="spin_enrollment_fee" tool_tip="Si la opción Cuota de entrada está marcada, los nuevos miembros han de pagar esta cuota para entrar al grupo." width="60"/>
- <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="La calificación de contenido designa el tipo de contenido y conducta que se permiten en un grupo" width="150">
+ <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="Establece si tu grupo contiene información clasificada como Moderada" width="150">
<combo_item name="select_mature">
- Selecciona el nivel de calificación -
</combo_item>
diff --git a/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..4d682068d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Desconocido"/>
+ <button name="info_btn" tool_tip="Más información"/>
+ <button name="profile_btn" tool_tip="Ver el perfil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_me.xml b/indra/newview/skins/default/xui/es/panel_me.xml
deleted file mode 100644
index 850cd6ec71..0000000000
--- a/indra/newview/skins/default/xui/es/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mi perfil" name="panel_me">
- <panel label="MIS DESTACADOS" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml
index 73b9af3665..2aaf7e89be 100644
--- a/indra/newview/skins/default/xui/es/panel_people.xml
+++ b/indra/newview/skins/default/xui/es/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Conectado"/>
<accordion_tab name="tab_all" title="Todos"/>
+ <accordion_tab name="tab_suggested_friends" title="Personas de las que podrías querer ser amigo"/>
</accordion>
</panel>
<panel label="GRUPOS" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_profile_classified.xml b/indra/newview/skins/default/xui/es/panel_profile_classified.xml
new file mode 100644
index 0000000000..679026d350
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderado
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenido general
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teleportes, [MAP] mapa, [PROFILE] perfil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Activados
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Inhabilitado
+ </panel.string>
+ <panel.string name="location_notice">
+ (se actualizará tras guardarlo)
+ </panel.string>
+ <string name="publish_label">
+ Publicar
+ </string>
+ <string name="save_label">
+ Guardar
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Pulsa para elegir una imagen"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Ubicación:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo de contenido:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoría:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Fecha de creación:"/>
+ <text_editor name="creation_date" tool_tip="Fecha de creación" value="[date]"/>
+ <text name="price_for_listing_label" value="Precio por publicarlo:"/>
+ <text_editor name="price_for_listing" tool_tip="Precio por publicarlo.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clics:"/>
+ <text_editor name="click_through_text" tool_tip="Información sobre Click through" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renovación:"/>
+ <text name="auto_renew" value="Activados"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descripción:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Título:
+ </text>
+ <text name="description_label">
+ Descripción:
+ </text>
+ <text name="location_label">
+ Ubicación:
+ </text>
+ <text name="classified_location_edit">
+ cargando...
+ </text>
+ <button label="Configurar en mi posición" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoría:"/>
+ <text name="content_type_label" value="Tipo de contenido:"/>
+ <icons_combo_box label="Contenido general" name="content_type_edit">
+ <icons_combo_box.item label="Contenido Moderado" name="mature_ci" value="Contenido para adultos"/>
+ <icons_combo_box.item label="Contenido general" name="pg_ci" value="General"/>
+ </icons_combo_box>
+ <check_box label="Renovar automáticamente cada semana" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Precio por publicarlo:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Precio por publicarlo." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teleporte" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mapa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Editar" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..2520348094
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Clasificado" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="No hay clasificados"/>
+ <button label="Nuevo..." name="new_btn"/>
+ <button label="Eliminar..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Cargando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml
index f058ff668b..0fb502e441 100644
--- a/indra/newview/skins/default/xui/fr/floater_picks.xml
+++ b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Favoris"/>
+<panel label="Perfil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_interests.xml b/indra/newview/skins/default/xui/es/panel_profile_interests.xml
new file mode 100644
index 0000000000..86dd63390c
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Intereses" name="panel_profile_interests">
+ <text name="I Want To:">
+ Quiero:
+ </text>
+ <check_box label="Construye" name="chk0"/>
+ <check_box label="Explora" name="chk1"/>
+ <check_box label="Conoce" name="chk2"/>
+ <check_box label="Encuentra empleo" name="chk6"/>
+ <check_box label="Agrupa" name="chk3"/>
+ <check_box label="Compra" name="chk4"/>
+ <check_box label="Vende" name="chk5"/>
+ <check_box label="Contrata" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (cargando...)
+ </line_editor>
+ <text name="Skills:">
+ Habilidades:
+ </text>
+ <check_box label="Texturas" name="schk0"/>
+ <check_box label="Arquitectura" name="schk1"/>
+ <check_box label="Modelo" name="schk3"/>
+ <check_box label="Planificación de eventos" name="schk2"/>
+ <check_box label="Preparación de scripts" name="schk4"/>
+ <check_box label="Personajes personalizados" name="schk5"/>
+ <line_editor name="skills_edit">
+ (cargando...)
+ </line_editor>
+ <text name="Languages:">
+ Idiomas:
+ </text>
+ <line_editor name="languages_edit">
+ (cargando...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_notes.xml b/indra/newview/skins/default/xui/es/panel_profile_notes.xml
new file mode 100644
index 0000000000..4cc14e1487
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notas y Privacidad" name="panel_notes">
+ <text name="status_message" value="Notas privadas en este avatar:"/>
+ <text name="status_message2" value="Permitir que este avatar:"/>
+ <check_box label="Ver cuándo estoy conectado" name="status_check"/>
+ <check_box label="Encontrarme en el mapa del mundo" name="map_check"/>
+ <check_box label="Edita, borrar o tomar mis objetos" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_pick.xml b/indra/newview/skins/default/xui/es/panel_profile_pick.xml
new file mode 100644
index 0000000000..4e9f5bbdd5
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (se actualizará tras guardarlo)
+ </panel.string>
+ <line_editor name="pick_location">
+ Cargando...
+ </line_editor>
+ <button label="Teleporte" name="teleport_btn"/>
+ <button label="Mostrar en el mapa" name="show_on_map_btn"/>
+ <button label="Establecer ubicación" name="set_to_curr_location_btn" tool_tip="Configurar en mi posición"/>
+ <button label="Guardar" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_picks.xml
new file mode 100644
index 0000000000..0641b72c13
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Destacados" name="panel_picks">
+ <string name="no_picks" value="No hay destacados"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Cuéntale a todos sobre tus lugares favoritos de Second Life.
+ </text>
+ <button label="Nuevo..." name="new_btn"/>
+ <button label="Eliminar..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Cargando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..541593660d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Perfil" name="panel_profile">
+ <string name="status_online">
+ Actualmente en línea
+ </string>
+ <string name="status_offline">
+ Actualmente sin conexión
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Ninguno"/>
+ <string name="no_group_text" value="Ninguno"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Desarrollador"/>
+ <string name="FSSupp" value="Soporte"/>
+ <string name="FSQualityAssurance" value="Buscador de fallos"/>
+ <string name="FSGW" value="Portal"/>
+ <text name="name_label" value="Nombre:"/>
+ <button label="Nombre:" name="set_name" tool_tip="Configurar nombre mostrado"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(cargando...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status Desconocido"/>
+ <text name="label" value="Fecha de nacimiento en Second Life:"/>
+ <text name="label2" value="Cuenta:"/>
+ <text name="partner_label" value="Compañero/a:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Grupos:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Invitar al grupo"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Acerca de:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Dar objeto:"/>
+ <text name="Give inventory" tool_tip="Soltar elementos de inventario aquí para dárselos a esta persona.">
+ Soltar aquí el nuevo elemento de inventario.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Encontrar en el mapa" label_selected="Encontrar en el mapa" name="show_on_map_btn" tool_tip="Mostrar al Residente en el mapa"/>
+ <button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pagar a este Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Ofrecer teleporte" label_selected="Ofrecer teleporte" name="teleport" tool_tip="Ofrecer teleporte al residente"/>
+ <button label="Mensaje instantáneo" label_selected="Mensaje instantáneo" name="im" tool_tip="Abrir una sesión de mensajes instantáneos"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Añadir como amigo" label_selected="Añadir como amigo" name="add_friend" tool_tip="Ofrecer amistad a este Residente"/>
+ <button label="Bloquear" name="block" tool_tip="Bloquear al residente"/>
+ <button label="Desbloquear" name="unblock" tool_tip="Desbloquear al residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostrar en la búsqueda" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_web.xml b/indra/newview/skins/default/xui/es/panel_profile_web.xml
new file mode 100644
index 0000000000..f9a8f4b113
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Tiempo de carga: [TIME] segundos"/>
+ <line_editor name="url_edit">
+ (cargando..)
+ </line_editor>
+ <flyout_button label="Cargar" name="load" tool_tip="Cargar esta página de perfil con el navegador incorporado.">
+ <flyout_button.item label="Abrir navegador in-viewer" name="open_item"/>
+ <flyout_button.item label="Abrir navegador externo" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Perfil web emergente"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
index cb6c03dbb5..9aba5299cb 100644
--- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
@@ -12,8 +12,8 @@ del terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Límite de bajada del
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas del terreno (requiere archivos .tga de 512x512, 24 bits)
- </text>
+ Texturas del terreno (requiere archivos .tga de 1024x1024, 24 bits)
+ </text>
<text name="height_text_lbl">
1 (bajo)
</text>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index e5598978ce..5a03e65b49 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -178,7 +178,7 @@ Versión del servidor de voz: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Error de red: no se ha podido conectar; por favor, revisa tu conexión a internet.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Error en el inicio de sesión.
</string>
<string name="Quit">
@@ -348,6 +348,24 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="TestingDisconnect">
Probando la desconexión del visor
</string>
+ <string name="SocialFacebookConnecting">
+ Conectando con Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Publicando...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Desconectando de Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problema al conectar con Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problema al publicar en Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problema al desconectar de Facebook
+ </string>
<string name="SocialFlickrConnecting">
Conectándose a Flickr...
</string>
@@ -662,9 +680,6 @@ pueden adjuntarse a las notas.
<string name="GroupNameNone">
(ninguno)
</string>
- <string name="AvalineCaller">
- Avaline: [ORDER]
- </string>
<string name="AssetErrorNone">
No hay ningún error
</string>
@@ -2549,9 +2564,21 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia
<string name="NoPicksClassifiedsText">
No has creado destacados ni clasificados. Pulsa el botón Más para crear uno.
</string>
+ <string name="NoPicksText">
+ No has creado destacados. Haz clic en el botón Más para crear uno.
+ </string>
+ <string name="NoClassifiedsText">
+ No has creado clasificados. Haz clic en el botón Nuevo para crear un anuncio clasificado.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
El usuario no tiene clasificados ni destacados
</string>
+ <string name="NoAvatarPicksText">
+ El usuario no tiene destacados
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ El usuario no tiene clasificados
+ </string>
<string name="PicksClassifiedsLoadingText">
Cargando...
</string>
@@ -4469,6 +4496,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="share_alert">
Arrastra los ítems desde el invenbtario hasta aquí
</string>
+ <string name="facebook_post_success">
+ Has publicado en Facebook.
+ </string>
<string name="flickr_post_success">
Has publicado en Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_facebook.xml b/indra/newview/skins/default/xui/fr/floater_facebook.xml
index f5097e7a88..f6e8696e53 100644
--- a/indra/newview/skins/default/xui/fr/floater_facebook.xml
+++ b/indra/newview/skins/default/xui/fr/floater_facebook.xml
@@ -10,6 +10,6 @@
Erreur
</text>
<text name="connection_loading_text">
- Chargement...
+ En cours de chargement...
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
index d63d9903ec..46703fe612 100644
--- a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copier dans l&apos;inventaire
</floater.string>
- <text name="desc txt">
- Description :
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Rapport d&apos;aspect fixe
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d&apos;aspect fixe">
- <combo_item name="Unconstrained">
- Sans contraintes
- </combo_item>
- <combo_item name="1:1" tool_tip="Logo du groupe ou profil dans la vie réelle">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Profil [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Petites annonces, repères">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="À propos du terrain">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Favoris du profil">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Jeter" name="Discard"/>
- <button label="Enregistrer sous" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Description :
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Rapport d&apos;aspect fixe
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d&apos;aspect fixe"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Jeter" name="Discard"/>
+ <button label="Enregistrer sous" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_profile.xml b/indra/newview/skins/default/xui/fr/floater_profile.xml
new file mode 100644
index 0000000000..c4af79e946
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Centres d&apos;intérêt" name="panel_profile_interests"/>
+ <panel label="Favoris" name="panel_profile_picks"/>
+ <panel label="Petite annonce" name="panel_profile_classifieds"/>
+ <panel label="Vie réelle" name="panel_profile_firstlife"/>
+ <panel label="Remarques" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Enregistrer les changements apportés au profil et fermer"/>
+ <button label="Annuler" label_selected="Annuler" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
index 8eb05dd945..adb98a68d2 100644
--- a/indra/newview/skins/default/xui/fr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Envoi par e-mail
</string>
+ <string name="facebook_progress_str">
+ Publication sur Facebook
+ </string>
<string name="profile_progress_str">
Publication
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Enregistrement sur l&apos;ordinateur
</string>
+ <string name="facebook_succeeded_str">
+ Image chargée
+ </string>
<string name="profile_succeeded_str">
Image chargée
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Enregistrement sur l&apos;ordinateur effectué !
</string>
+ <string name="facebook_failed_str">
+ Échec de chargement de l&apos;image dans votre journal Facebook.
+ </string>
<string name="profile_failed_str">
Échec de chargement de l&apos;image sur le flux de votre profil.
</string>
diff --git a/indra/newview/skins/default/xui/fr/menu_name_field.xml b/indra/newview/skins/default/xui/fr/menu_name_field.xml
new file mode 100644
index 0000000000..6c3fba4110
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copier le Nom d&apos;affichage" name="copy_display"/>
+ <menu_item_call label="Copier le Nom de l&apos;agent" name="copy_name"/>
+ <menu_item_call label="Copier l&apos;ID de l&apos;agent" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index e84de375d8..09905f4e5d 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2683,6 +2683,9 @@ Veuillez sélectionner un terrain plus petit.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
index 7b58f2e825..b892d25f26 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Annuler" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
index 319737a2af..0e36c2092c 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Vous n&apos;avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life !"/>
+ <string name="facebook_friends_empty" value="Vous n&apos;avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life aujourd&apos;hui !"/>
<string name="facebook_friends_no_connected" value="Vous n&apos;êtes pas connecté(e) à Facebook. Allez à l&apos;onglet Statut pour vous connecter et activer cette fonctionnalité."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Amis SL"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
index 3236f35b55..cc4045bc74 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
@@ -4,14 +4,14 @@
<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
<combo_box.item label="640 x 480" name="640x480"/>
<combo_box.item label="800 x 600" name="800x600"/>
- <combo_box.item label="1 024 x 768" name="1024x768"/>
- <combo_box.item label="1 200 x 630" name="1200x630"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
- <combo_box name="filters_combobox" tool_tip="Filtres d&apos;image">
+ <combo_box name="filters_combobox" tool_tip="Filtres d’image">
<combo_box.item label="Aucun filtre" name="NoFilter"/>
</combo_box>
<button label="Actualiser" name="new_snapshot_btn" tool_tip="Cliquer pour actualiser"/>
- <button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour activer/désactiver l&apos;aperçu"/>
+ <button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour basculer l&apos;aperçu"/>
<text name="caption_label">
Commentaire (facultatif) :
</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
index 9afa42d2aa..dc8e4b9ecc 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
@@ -6,7 +6,7 @@
Pas connecté(e) à Facebook.
</text>
<panel name="panel_buttons">
- <button label="Connexion..." name="connect_btn"/>
+ <button label="Connexion en cours..." name="connect_btn"/>
<button label="Déconnexion" name="disconnect_btn"/>
<text name="account_learn_more_label">
[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Apprenez comment publier sur Facebook]
diff --git a/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..b1b32af7c6
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Inconnu"/>
+ <button name="info_btn" tool_tip="En savoir plus"/>
+ <button name="profile_btn" tool_tip="Voir le profil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_me.xml b/indra/newview/skins/default/xui/fr/panel_me.xml
deleted file mode 100644
index 5676986228..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mon profil" name="panel_me">
- <panel label="MES FAVORIS" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index 3be6bae52a..e096b5cfe0 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -40,6 +40,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="En ligne"/>
<accordion_tab name="tab_all" title="Tout"/>
+ <accordion_tab name="tab_suggested_friends" title="Personnes avec lesquelles vous aimeriez peut-être devenir ami(e)"/>
</accordion>
</panel>
<panel label="GROUPES" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classified.xml b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml
new file mode 100644
index 0000000000..b223684c60
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Modéré
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenu Général
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] téléporter, [MAP] carte, [PROFILE] profile
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Activé
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Désactivé
+ </panel.string>
+ <panel.string name="location_notice">
+ (mise à jour après enregistrement)
+ </panel.string>
+ <string name="publish_label">
+ Publier
+ </string>
+ <string name="save_label">
+ Enregistrer
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Cliquer pour sélectionner une image"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Endroit :"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Type de contenu :"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Catégorie :"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Date de création :"/>
+ <text_editor name="creation_date" tool_tip="Date de création" value="[date]"/>
+ <text name="price_for_listing_label" value="Coût de l&apos;annonce :"/>
+ <text_editor name="price_for_listing" tool_tip="Coût de l’annonce.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clics :"/>
+ <text_editor name="click_through_text" tool_tip="Parcourir les données en cliquant" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renouv. auto :"/>
+ <text name="auto_renew" value="Activé"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Description :"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titre :
+ </text>
+ <text name="description_label">
+ Description :
+ </text>
+ <text name="location_label">
+ Endroit :
+ </text>
+ <text name="classified_location_edit">
+ en cours de chargement...
+ </text>
+ <button label="Définir sur l’emplacement actuel" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Catégorie :"/>
+ <text name="content_type_label" value="Type de contenu :"/>
+ <icons_combo_box label="Contenu Général" name="content_type_edit">
+ <icons_combo_box.item label="Contenu Modéré" name="mature_ci" value="Adulte"/>
+ <icons_combo_box.item label="Contenu Général" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Renouvellement auto toutes les semaines" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Coût de l&apos;annonce :"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Coût de l’annonce." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Téléportation" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Carte" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Modifier" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Annuler" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..adb3501422
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Petite annonce" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Pas de petites annonces"/>
+ <button label="Nouveau..." name="new_btn"/>
+ <button label="Supprimer..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ En cours de chargement...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/floater_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml
index 255aa5dcdc..0f65090209 100644
--- a/indra/newview/skins/default/xui/es/floater_picks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Destacados"/>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_interests.xml b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml
new file mode 100644
index 0000000000..e8212817d2
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Centres d&apos;intérêt" name="panel_profile_interests">
+ <text name="I Want To:">
+ Je veux :
+ </text>
+ <check_box label="Construire" name="chk0"/>
+ <check_box label="Explorer" name="chk1"/>
+ <check_box label="Rencontrer" name="chk2"/>
+ <check_box label="Être recruté" name="chk6"/>
+ <check_box label="Grouper" name="chk3"/>
+ <check_box label="Acheter" name="chk4"/>
+ <check_box label="Vendre" name="chk5"/>
+ <check_box label="Louer" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (en cours de chargement...)
+ </line_editor>
+ <text name="Skills:">
+ Compétences :
+ </text>
+ <check_box label="Textures" name="schk0"/>
+ <check_box label="Architecture" name="schk1"/>
+ <check_box label="Modèle" name="schk3"/>
+ <check_box label="Planification des événements" name="schk2"/>
+ <check_box label="Langage de scripts" name="schk4"/>
+ <check_box label="Personnages personnalisés" name="schk5"/>
+ <line_editor name="skills_edit">
+ (en cours de chargement...)
+ </line_editor>
+ <text name="Languages:">
+ Langues :
+ </text>
+ <line_editor name="languages_edit">
+ (en cours de chargement...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_notes.xml b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml
new file mode 100644
index 0000000000..03fb37d72b
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notes &amp; respect de la vie privée" name="panel_notes">
+ <text name="status_message" value="Notes personnelles sur cet avatar:"/>
+ <text name="status_message2" value="Autoriser cet avatar à :"/>
+ <check_box label="Voir quand je suis en ligne" name="status_check"/>
+ <check_box label="Me trouver sur la carte du monde" name="map_check"/>
+ <check_box label="Modifier, supprimer ou prendre mes objets" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_pick.xml b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml
new file mode 100644
index 0000000000..017fcff88a
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (mise à jour après enregistrement)
+ </panel.string>
+ <line_editor name="pick_location">
+ En cours de chargement...
+ </line_editor>
+ <button label="Téléportation" name="teleport_btn"/>
+ <button label="Voir sur la carte" name="show_on_map_btn"/>
+ <button label="Définir l&apos;emplacement" name="set_to_curr_location_btn" tool_tip="Définir sur l’emplacement actuel"/>
+ <button label="Enregistrer les favoris" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml
new file mode 100644
index 0000000000..1644722813
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Favoris" name="panel_picks">
+ <string name="no_picks" value="Pas de favoris"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Faites connaître aux autres résidents vos endroits favoris dans Second Life.
+ </text>
+ <button label="Nouveau..." name="new_btn"/>
+ <button label="Supprimer..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ En cours de chargement...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..de9cbf6dce
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Actuellement connecté
+ </string>
+ <string name="status_offline">
+ Actuellement déconnecté
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Aucun"/>
+ <string name="no_group_text" value="Aucun"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Développeur"/>
+ <string name="FSSupp" value="Assistance"/>
+ <string name="FSQualityAssurance" value="Suivi des anomalies"/>
+ <string name="FSGW" value="Portail"/>
+ <text name="name_label" value="Nom :"/>
+ <button label="Nom :" name="set_name" tool_tip="Définir un nom d&apos;affichage"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(en cours de chargement...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Statut inconnu"/>
+ <text name="label" value="Date de naissance dans Second Life :"/>
+ <text name="label2" value="Compte :"/>
+ <text name="partner_label" value="Partenaire :"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Groupes :"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Inviter dans le groupe"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="À propos :"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Donner des objets :"/>
+ <text name="Give inventory" tool_tip="Placer les objets de l&apos;inventaire ici pour les donner à cette personne">
+ Placer les objets de l&apos;inventaire ici.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Situer sur la carte" label_selected="Situer sur la carte" name="show_on_map_btn" tool_tip="Localiser le Résident sur la carte"/>
+ <button label="Payer" label_selected="Payer" name="pay" tool_tip="Payer le résident"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Proposer de téléporter" label_selected="Proposer de téléporter" name="teleport" tool_tip="Proposer une téléportation au Résident"/>
+ <button label="Message instantané" label_selected="Message instantané" name="im" tool_tip="Ouvrir une session IM."/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Ajouter un ami" label_selected="Ajouter un ami" name="add_friend" tool_tip="Proposer à ce résident de devenir votre ami"/>
+ <button label="Bloquer" name="block" tool_tip="Bloquer ce Résident"/>
+ <button label="Débloquer" name="unblock" tool_tip="Débloquer ce Résident"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Afficher avec la recherche" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_web.xml b/indra/newview/skins/default/xui/fr/panel_profile_web.xml
new file mode 100644
index 0000000000..70e145ade9
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Heure de chargement : [TIME] secondes"/>
+ <line_editor name="url_edit">
+ (en cours de chargement..)
+ </line_editor>
+ <flyout_button label="Charger" name="load" tool_tip="Charger ce profil avec le navigateur Web incorporé">
+ <flyout_button.item label="Ouvrir dans mon navigateur Web" name="open_item"/>
+ <flyout_button.item label="Ouvrir dans un navigateur externe" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Profil de fenêtres web"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
index 97f486d3a3..bbab00ca24 100644
--- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terrain" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite d&apos;abaissement
du terrain" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Textures du terrain (fichiers .tga 512 x 512, 24 bit requis)
- </text>
+ Textures du terrain (fichiers .tga 1024 x 1024, 24 bit requis)
+ </text>
<text name="height_text_lbl">
1 (Bas)
</text>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index f7545f08d2..21825c6b2f 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -187,7 +187,7 @@ Voice Server Version: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Erreur réseau : impossible d&apos;établir la connexion. Veuillez vérifier votre connexion réseau.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Échec de la connexion.
</string>
<string name="Quit">
@@ -357,6 +357,24 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="TestingDisconnect">
Test de déconnexion du client
</string>
+ <string name="SocialFacebookConnecting">
+ Connexion à Facebook…
+ </string>
+ <string name="SocialFacebookPosting">
+ Publication…
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Déconnexion de Facebook…
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Un problème est survenu lors de la connexion à Facebook.
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Un problème est survenu lors de la publication sur Facebook.
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Un problème est survenu lors de la déconnexion à Facebook.
+ </string>
<string name="SocialFlickrConnecting">
Connexion à Flickr...
</string>
@@ -674,9 +692,6 @@ peuvent être joints aux notes.
<string name="GroupNameNone">
(aucun)
</string>
- <string name="AvalineCaller">
- Appelant Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Aucune erreur
</string>
@@ -2579,9 +2594,21 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life
<string name="NoPicksClassifiedsText">
Vous n&apos;avez pas créé de favoris ni de petites annonces Cliquez sur le bouton Plus pour créer un favori ou une petite annonce.
</string>
+ <string name="NoPicksText">
+ Vous n&apos;avez pas créé de favoris Cliquer sur le bouton Nouveau pour créer un favori
+ </string>
+ <string name="NoClassifiedsText">
+ Vous n&apos;avez pas créé de petites annonces Cliquer sur le bouton Nouveau pour créer une petite annonce.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
L&apos;utilisateur n&apos;a ni favoris ni petites annonces.
</string>
+ <string name="NoAvatarPicksText">
+ L&apos;utilisateur n&apos;a pas de favoris
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ L&apos;utilisateur n&apos;a pas de petites annonces
+ </string>
<string name="PicksClassifiedsLoadingText">
Chargement...
</string>
@@ -4559,6 +4586,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="share_alert">
Faire glisser les objets de l&apos;inventaire ici
</string>
+ <string name="facebook_post_success">
+ Vous avez publié sur Facebook.
+ </string>
<string name="flickr_post_success">
Vous avez publié sur Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_preview_texture.xml b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
index 8e8d020067..02f15b6b7b 100644
--- a/indra/newview/skins/default/xui/it/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copia nell&apos;Inventario
</floater.string>
- <text name="desc txt">
- Descrizione:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Antreprima rapporto di visualizzazione
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso">
- <combo_item name="Unconstrained">
- Libero
- </combo_item>
- <combo_item name="1:1" tool_tip="Logo del gruppo o profilo nel mondo reale">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Profilo [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Annunci e inserzioni, punti di riferimento">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Informazioni sul terreno">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Preferiti del Profilo">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Elimina" name="Discard"/>
- <button label="Salva con nome" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descrizione:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Antreprima rapporto di visualizzazione
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Elimina" name="Discard"/>
+ <button label="Salva con nome" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_profile.xml b/indra/newview/skins/default/xui/it/floater_profile.xml
new file mode 100644
index 0000000000..7e23f9bbbb
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profilo">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interessi" name="panel_profile_interests"/>
+ <panel label="Preferiti" name="panel_profile_picks"/>
+ <panel label="Annuncio" name="panel_profile_classifieds"/>
+ <panel label="Vita reale" name="panel_profile_firstlife"/>
+ <panel label="Note" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salva modifiche al profilo e chiudi"/>
+ <button label="Annulla" label_selected="Annulla" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_snapshot.xml b/indra/newview/skins/default/xui/it/floater_snapshot.xml
index d21c206f6f..c9f71a167e 100644
--- a/indra/newview/skins/default/xui/it/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/it/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Invio e-mail in corso
</string>
+ <string name="facebook_progress_str">
+ Pubblicazione su Facebook in corso
+ </string>
<string name="profile_progress_str">
Caricamento post
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Salvataggio sul computer in corso
</string>
+ <string name="facebook_succeeded_str">
+ Immagine caricata
+ </string>
<string name="profile_succeeded_str">
Immagine caricata
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Salvato sul computer.
</string>
+ <string name="facebook_failed_str">
+ Caricamento immagine sul diario di Facebook non riuscito.
+ </string>
<string name="profile_failed_str">
Caricamento immagine sul feed del profilo non riuscito.
</string>
diff --git a/indra/newview/skins/default/xui/it/menu_name_field.xml b/indra/newview/skins/default/xui/it/menu_name_field.xml
new file mode 100644
index 0000000000..9ac863323c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copia Nome Visualizzato" name="copy_display"/>
+ <menu_item_call label="Copia Nome Agente" name="copy_name"/>
+ <menu_item_call label="Copia ID Agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 1c43013255..a69fa07c50 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -2685,6 +2685,9 @@ Prova a selezionare una parte di terreno più piccola.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_classified.xml b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
index ad827696ff..57e422a25b 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Annulla" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
index c1c0489f88..28769a010f 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti in Second Life. Invita i tuoi amici di Facebook a partecipare a Second Life!"/>
- <string name="facebook_friends_no_connected" value="Attualmente non sei in collegamento con Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>
+ <string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti Second Life. Invita ora i tuoi amici di Facebook a unirsi a Second Life!"/>
+ <string name="facebook_friends_no_connected" value="Non sei connesso a Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Amici SL"/>
<accordion_tab name="tab_suggested_friends" title="Aggiungi queste persone come amici SL"/>
</accordion>
<text name="facebook_friends_status">
- Non in collegamento con Facebook.
+ Non connesso a Facebook.
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
index 044b8b6164..8d66f35c3c 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_photo">
- <combo_box name="resolution_combobox" tool_tip="Risoluzione immagini">
+ <combo_box name="resolution_combobox" tool_tip="Risoluzione immagine">
<combo_box.item label="Finestra attuale" name="CurrentWindow"/>
<combo_box.item label="640x480" name="640x480"/>
<combo_box.item label="800x600" name="800x600"/>
<combo_box.item label="1024x768" name="1024x768"/>
<combo_box.item label="1200x630" name="1200x630"/>
</combo_box>
- <combo_box name="filters_combobox" tool_tip="Filtri immagini">
+ <combo_box name="filters_combobox" tool_tip="Filtri immagine">
<combo_box.item label="Nessun filtro" name="NoFilter"/>
</combo_box>
<button label="Aggiorna" name="new_snapshot_btn" tool_tip="Fai clic per aggiornare"/>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_status.xml b/indra/newview/skins/default/xui/it/panel_facebook_status.xml
index 9b5171043a..7fb1cec78e 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_status.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
- <string name="facebook_connected" value="Sei in collegamento con Facebook come:"/>
- <string name="facebook_disconnected" value="Non in collegamento con Facebook"/>
+ <string name="facebook_connected" value="Sei connesso a Facebook come:"/>
+ <string name="facebook_disconnected" value="Non connesso a Facebook"/>
<text name="account_caption_label">
- Non in collegamento con Facebook.
+ Non connesso a Facebook.
</text>
<panel name="panel_buttons">
- <button label="Collegamento..." name="connect_btn"/>
- <button label="Interrompi collegamento" name="disconnect_btn"/>
+ <button label="Connessione in corso..." name="connect_btn"/>
+ <button label="Disconnetti" name="disconnect_btn"/>
<text name="account_learn_more_label">
[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Come pubblicare su Facebook]
</text>
diff --git a/indra/newview/skins/default/xui/it/panel_group_general.xml b/indra/newview/skins/default/xui/it/panel_group_general.xml
index 60028e6098..168524d1ad 100644
--- a/indra/newview/skins/default/xui/it/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_general.xml
@@ -46,7 +46,7 @@ Muovi il tuo mouse sopra le opzioni per maggiore aiuto.
<check_box label="Chiunque può aderire" name="open_enrollement" tool_tip="Imposta se questo gruppo permette ai nuovi membri di aderire senza essere invitati."/>
<check_box label="Quota di adesione" name="check_enrollment_fee" tool_tip="Imposta se richiedere una tassa d&apos;iscrizione per aderire al gruppo"/>
<spinner label="L$" left_delta="136" name="spin_enrollment_fee" tool_tip="I nuovi soci devono pagare questa tassa d&apos;iscrizione quando è selezionata." width="60"/>
- <combo_box name="group_mature_check" tool_tip="Le categorie di accesso definiscono il tipo di contenuti e di comportamenti ammessi in un gruppo">
+ <combo_box name="group_mature_check" tool_tip="Determina se il tuo gruppo contiene informazioni contrassegnate come Moderate opppure no">
<combo_item name="select_mature">
- Seleziona categoria di accesso -
</combo_item>
diff --git a/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..72e644008c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Sconosciuto"/>
+ <button name="info_btn" tool_tip="Maggiori informazioni"/>
+ <button name="profile_btn" tool_tip="Vedi profilo"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_me.xml b/indra/newview/skins/default/xui/it/panel_me.xml
deleted file mode 100644
index a134f6f1de..0000000000
--- a/indra/newview/skins/default/xui/it/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Il mio profilo" name="panel_me">
- <panel label="I MIEI PREFERITI" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml
index 3df2368ae0..9eb93a26e5 100644
--- a/indra/newview/skins/default/xui/it/panel_people.xml
+++ b/indra/newview/skins/default/xui/it/panel_people.xml
@@ -40,6 +40,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Tutto"/>
+ <accordion_tab name="tab_suggested_friends" title="Persone che potresti voler aggiungere agli amici"/>
</accordion>
</panel>
<panel label="GRUPPI" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/it/panel_profile_classified.xml b/indra/newview/skins/default/xui/it/panel_profile_classified.xml
new file mode 100644
index 0000000000..3c88fbe92f
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderato
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenuto Generale
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teletrasporto, [MAP] mappa, [PROFILE] profilo
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Abilitato
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Disabilitato
+ </panel.string>
+ <panel.string name="location_notice">
+ (si aggiornerà dopo il salvataggio)
+ </panel.string>
+ <string name="publish_label">
+ Pubblica
+ </string>
+ <string name="save_label">
+ Salva
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Fai clic per selezionare un&apos;immagine"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Posizione:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo di contenuto:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoria:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Data di creazione:"/>
+ <text_editor name="creation_date" tool_tip="Data di creazione" value="[date]"/>
+ <text name="price_for_listing_label" value="Prezzo per inserzione:"/>
+ <text_editor name="price_for_listing" tool_tip="Prezzo per inserzione.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clic:"/>
+ <text_editor name="click_through_text" tool_tip="Numero di clic" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Rinnovo automatico:"/>
+ <text name="auto_renew" value="Abilitato"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descrizione:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titolo:
+ </text>
+ <text name="description_label">
+ Descrizione:
+ </text>
+ <text name="location_label">
+ Posizione:
+ </text>
+ <text name="classified_location_edit">
+ caricamento in corso...
+ </text>
+ <button label="Imposta come Luogo Attuale" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoria:"/>
+ <text name="content_type_label" value="Tipo di contenuto:"/>
+ <icons_combo_box label="Contenuto Generale" name="content_type_edit">
+ <icons_combo_box.item label="Contenuto Moderato" name="mature_ci" value="Per adulti"/>
+ <icons_combo_box.item label="Contenuto Generale" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Rinnovo automatico ogni settimana" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Prezzo per inserzione:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Prezzo per inserzione." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teletrasporto" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mappa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Modifica" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Annulla" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..6fc0fd0729
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Annuncio" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Nessuno annuncio"/>
+ <button label="Nuovo..." name="new_btn"/>
+ <button label="Elimina..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Caricamento in corso...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..bf8ccef273
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profilo" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_interests.xml b/indra/newview/skins/default/xui/it/panel_profile_interests.xml
new file mode 100644
index 0000000000..9fe7331e5c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interessi" name="panel_profile_interests">
+ <text name="I Want To:">
+ Desidero:
+ </text>
+ <check_box label="Costruire" name="chk0"/>
+ <check_box label="Esplorare" name="chk1"/>
+ <check_box label="Incontrare" name="chk2"/>
+ <check_box label="Essere assunto" name="chk6"/>
+ <check_box label="Gruppo" name="chk3"/>
+ <check_box label="Acquistare" name="chk4"/>
+ <check_box label="Vendere" name="chk5"/>
+ <check_box label="Assumere" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (caricamento in corso...)
+ </line_editor>
+ <text name="Skills:">
+ Abilità:
+ </text>
+ <check_box label="Texture" name="schk0"/>
+ <check_box label="Architettura" name="schk1"/>
+ <check_box label="Realizzazione modelli 3D" name="schk3"/>
+ <check_box label="Organizzazione eventi" name="schk2"/>
+ <check_box label="Scripting" name="schk4"/>
+ <check_box label="Personaggi personalizzati" name="schk5"/>
+ <line_editor name="skills_edit">
+ (caricamento in corso...)
+ </line_editor>
+ <text name="Languages:">
+ Lingue:
+ </text>
+ <line_editor name="languages_edit">
+ (caricamento in corso...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_notes.xml b/indra/newview/skins/default/xui/it/panel_profile_notes.xml
new file mode 100644
index 0000000000..abd5a347c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Note e Privacy" name="panel_notes">
+ <text name="status_message" value="Annotazioni private su questo avatar:"/>
+ <text name="status_message2" value="Consenti a questo avatar di:"/>
+ <check_box label="Vedere quando sono in linea" name="status_check"/>
+ <check_box label="Trovarmi sulla mappa del mondo" name="map_check"/>
+ <check_box label="Modificare, eliminare o prendere i miei oggetti" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_pick.xml b/indra/newview/skins/default/xui/it/panel_profile_pick.xml
new file mode 100644
index 0000000000..5d2b145565
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (si aggiornerà dopo il salvataggio)
+ </panel.string>
+ <line_editor name="pick_location">
+ Caricamento in corso...
+ </line_editor>
+ <button label="Teletrasporto" name="teleport_btn"/>
+ <button label="Mostra sulla mappa" name="show_on_map_btn"/>
+ <button label="Imposta Luogo" name="set_to_curr_location_btn" tool_tip="Imposta come Luogo Attuale"/>
+ <button label="Salva Luogo preferito" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_picks.xml b/indra/newview/skins/default/xui/it/panel_profile_picks.xml
new file mode 100644
index 0000000000..37cffcf622
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Preferiti" name="panel_picks">
+ <string name="no_picks" value="Nessun preferito"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Comunica a tutti quali sono i tuoi posti preferiti in Second Life.
+ </text>
+ <button label="Nuovo..." name="new_btn"/>
+ <button label="Elimina..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Caricamento in corso...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..47af1960a5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profilo" name="panel_profile">
+ <string name="status_online">
+ Ora in linea
+ </string>
+ <string name="status_offline">
+ Ora non in linea
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Nessuno"/>
+ <string name="no_group_text" value="Nessuno"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Sviluppatore"/>
+ <string name="FSSupp" value="Assistenza"/>
+ <string name="FSQualityAssurance" value="Bug Hunter"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Nome:"/>
+ <button label="Nome:" name="set_name" tool_tip="Imposta nome visualizzato"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(caricamento in corso...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Stato Sconosciuto"/>
+ <text name="label" value="Compleanno Second Life:"/>
+ <text name="label2" value="Account:"/>
+ <text name="partner_label" value="Partner:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruppi:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Invita al gruppo:"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Informazioni generali:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Consegna oggetto:"/>
+ <text name="Give inventory" tool_tip="Rilascia gli oggetti dell’inventario per consegnarli a questa persona.">
+ Rilascia l’oggetto dell’inventario qui.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Trova sulla mappa" label_selected="Trova sulla mappa" name="show_on_map_btn" tool_tip="Localizza il Residente sulla mappa"/>
+ <button label="Paga" label_selected="Paga" name="pay" tool_tip="Paga del denaro al Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Offri Teletrasporto" label_selected="Offri Teletrasporto" name="teleport" tool_tip="Offri il teletrasporto al Residente"/>
+ <button label="Messaggio istantaneo" label_selected="Messaggio istantaneo" name="im" tool_tip="Apri sessione di messaggistica istantanea"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Aggiungi come amico" label_selected="Aggiungi come amico" name="add_friend" tool_tip="Offri amicizia al Residente"/>
+ <button label="Blocca" name="block" tool_tip="Blocca questo Residente"/>
+ <button label="Sblocca" name="unblock" tool_tip="Sblocca questo Residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostra nella ricerca" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_web.xml b/indra/newview/skins/default/xui/it/panel_profile_web.xml
new file mode 100644
index 0000000000..0c3a8ddcf5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Tempo di caricamento: [TIME] secondi"/>
+ <line_editor name="url_edit">
+ (caricamento in corso..)
+ </line_editor>
+ <flyout_button label="Carica" name="load" tool_tip="Carica la pagina profilo con il browser Web integrato.">
+ <flyout_button.item label="Apri browser interno" name="open_item"/>
+ <flyout_button.item label="Apri browser esterno" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Profilo web a comparsa"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
index c61ac3ecce..e08c55f63b 100644
--- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite di abbassamento
del terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texture terreno (richiede file 512x512, 24 bit .tga)
- </text>
+ Texture terreno (richiede file 1024x1024, 24 bit .tga)
+ </text>
<text name="height_text_lbl">
1 (basso)
</text>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 7690e02692..1ebdadb930 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -183,7 +183,7 @@ Versione server voce: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Errore di rete: Non è stato possibile stabilire un collegamento, controlla la tua connessione.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Accesso non riuscito.
</string>
<string name="Quit">
@@ -353,6 +353,24 @@ Prova ad accedere nuovamente tra un minuto.
<string name="TestingDisconnect">
Verifica scollegamento viewer
</string>
+ <string name="SocialFacebookConnecting">
+ Connessione a Facebook in corso...
+ </string>
+ <string name="SocialFacebookPosting">
+ Caricamento post...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Disconnessione da Facebook in corso...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problemi con la connessione a Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problemi con la connessione a Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problemi con la disconnessione da Facebook
+ </string>
<string name="SocialFlickrConnecting">
Collegamento a Flickr...
</string>
@@ -667,9 +685,6 @@ possono essere allegati ai biglietti.
<string name="GroupNameNone">
(nessuno)
</string>
- <string name="AvalineCaller">
- Chiamante Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Nessun errore
</string>
@@ -2557,9 +2572,21 @@ Se continui a ricevere questo messaggio, contatta l&apos;assistenza Second Life
<string name="NoPicksClassifiedsText">
Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un&apos;inserzione.
</string>
+ <string name="NoPicksText">
+ Non hai creato Luoghi preferiti. Fai clic sul pulsante Nuovo per creare un Luogo preferito.
+ </string>
+ <string name="NoClassifiedsText">
+ Non hai creato Annunci. Fai clic sul pulsante Nuovo per creare un Annuncio.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
L&apos;utente non ha luoghi preferiti né inserzioni
</string>
+ <string name="NoAvatarPicksText">
+ L&apos;utente non ha luoghi preferiti
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ L&apos;utente non ha annunci
+ </string>
<string name="PicksClassifiedsLoadingText">
Caricamento in corso...
</string>
@@ -4474,6 +4501,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="inventory_folder_offered-im">
Offerta cartella di inventario &quot;[ITEM_NAME]&quot;
</string>
+ <string name="facebook_post_success">
+ Hai pubblicato su Facebook.
+ </string>
<string name="flickr_post_success">
Hai pubblicato su Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_picks.xml b/indra/newview/skins/default/xui/ja/floater_picks.xml
deleted file mode 100644
index 359585eb86..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="ピック"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
index 4617fd1d92..66ef13948a 100644
--- a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
インベントリにコピー
</floater.string>
- <text name="desc txt">
- 説明:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- 縦横比のプレビュー
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー">
- <combo_item name="Unconstrained">
- 非拘束
- </combo_item>
- <combo_item name="1:1" tool_tip="グループ記章か現実世界のプロフィール">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] プロフィール">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="クラシファイド広告、検索一覧、ランドマーク">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="土地情報">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="プロフィールのピック">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="処分する" name="Discard"/>
- <button label="別名で保存" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ 説明:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ 縦横比のプレビュー
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="処分する" name="Discard"/>
+ <button label="別名で保存" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_profile.xml b/indra/newview/skins/default/xui/ja/floater_profile.xml
new file mode 100644
index 0000000000..e06cd6e8f6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="プロフィール">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="趣味" name="panel_profile_interests"/>
+ <panel label="ピック" name="panel_profile_picks"/>
+ <panel label="クラシファイド広告" name="panel_profile_classifieds"/>
+ <panel label="リアルライフ(現実世界)" name="panel_profile_firstlife"/>
+ <panel label="メモ" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="プロフィールの変更を保存して閉じる"/>
+ <button label="キャンセル" label_selected="キャンセル" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
index f04193d034..64f292c75c 100644
--- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
メールの送信
</string>
+ <string name="facebook_progress_str">
+ Facebook へ投稿中
+ </string>
<string name="profile_progress_str">
投稿
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
コンピュータに保存
</string>
+ <string name="facebook_succeeded_str">
+ 画像がアップロードされました
+ </string>
<string name="profile_succeeded_str">
画像がアップロードされました
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
コンピュータに保存されました
</string>
+ <string name="facebook_failed_str">
+ Facebook のタイムラインに画像をアップロードできませんでした。
+ </string>
<string name="profile_failed_str">
プロフィールフィードに画像をアップロードできませんでした。
</string>
diff --git a/indra/newview/skins/default/xui/ja/menu_name_field.xml b/indra/newview/skins/default/xui/ja/menu_name_field.xml
new file mode 100644
index 0000000000..8c37d95073
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="表示名をコピー" name="copy_display"/>
+ <menu_item_call label="エージェント名をコピー" name="copy_name"/>
+ <menu_item_call label="エージェント ID をコピー" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index a66552d3fe..92952f4c8a 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -2727,6 +2727,9 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
index cf5f2489f1..619e9de65a 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="キャンセル" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
index c48f13456b..ee57d178e8 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
@@ -16,5 +16,5 @@
コメント (オプション):
</text>
<button label="投稿" name="post_photo_btn"/>
- <button label="取り消し" name="cancel_photo_btn"/>
+ <button label="キャンセル" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
index 61138f90c1..e97422a9df 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
@@ -5,5 +5,5 @@
</text>
<check_box initial_value="false" label="場所の俯瞰図を含める" name="add_place_view_cb"/>
<button label="投稿" name="post_place_btn"/>
- <button label="取り消し" name="cancel_place_btn"/>
+ <button label="キャンセル" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
index 9d962c9d62..1f48c9c8c7 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
@@ -9,12 +9,12 @@
<button label="接続..." name="connect_btn"/>
<button label="切断" name="disconnect_btn"/>
<text name="account_learn_more_label">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]]
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]
</text>
</panel>
<text name="status_caption_label">
今、何を考えている?
</text>
<button label="投稿" name="post_status_btn"/>
- <button label="取り消し" name="cancel_status_btn"/>
+ <button label="キャンセル" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..77d3d8f391
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="不明"/>
+ <button name="info_btn" tool_tip="詳細"/>
+ <button name="profile_btn" tool_tip="プロフィールの表示"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml
deleted file mode 100644
index 9b1cf1c8a4..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="プロフィール" name="panel_me">
- <panel label="マイ ピック" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml
index 0a295855d0..be00a3c122 100644
--- a/indra/newview/skins/default/xui/ja/panel_people.xml
+++ b/indra/newview/skins/default/xui/ja/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="オンライン"/>
<accordion_tab name="tab_all" title="全員"/>
+ <accordion_tab name="tab_suggested_friends" title="友だちになりたくない人"/>
</accordion>
</panel>
<panel label="グループ" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classified.xml b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml
new file mode 100644
index 0000000000..2d1bc07e2c
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderate
+ </panel.string>
+ <panel.string name="type_pg">
+ General コンテンツ
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] テレポート、 [MAP] 地図、 [PROFILE] プロフィール
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ 有効
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ 無効
+ </panel.string>
+ <panel.string name="location_notice">
+ (掲載後更新)
+ </panel.string>
+ <string name="publish_label">
+ 掲載
+ </string>
+ <string name="save_label">
+ 保存
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="クリックして画像を選択"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="場所:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="コンテンツの種類:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="カテゴリ:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="制作日:"/>
+ <text_editor name="creation_date" tool_tip="制作日" value="[date]"/>
+ <text name="price_for_listing_label" value="掲載価格:"/>
+ <text_editor name="price_for_listing" tool_tip="掲載価格。">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="クリック数:"/>
+ <text_editor name="click_through_text" tool_tip="クリックスルーデータ" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="自動更新:"/>
+ <text name="auto_renew" value="有効"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="説明:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ タイトル:
+ </text>
+ <text name="description_label">
+ 説明:
+ </text>
+ <text name="location_label">
+ 場所:
+ </text>
+ <text name="classified_location_edit">
+ ロード中...
+ </text>
+ <button label="現在地に設定" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="カテゴリ:"/>
+ <text name="content_type_label" value="コンテンツの種類:"/>
+ <icons_combo_box label="General コンテンツ" name="content_type_edit">
+ <icons_combo_box.item label="Moderate コンテンツ" name="mature_ci" value="Mature"/>
+ <icons_combo_box.item label="General コンテンツ" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="毎週自動更新" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="掲載価格:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="掲載価格。" value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="テレポート" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="地図" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="編集" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="キャンセル" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..1980c0fa62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="クラシファイド広告" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="クラシファイド広告なし"/>
+ <button label="新規…" name="new_btn"/>
+ <button label="削除…" name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ ロード中...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..a4ee262cb3
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="プロフィール" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_interests.xml b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml
new file mode 100644
index 0000000000..93cde6ffec
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="趣味" name="panel_profile_interests">
+ <text name="I Want To:">
+ 次の内容を実行:
+ </text>
+ <check_box label="作る" name="chk0"/>
+ <check_box label="探検" name="chk1"/>
+ <check_box label="出会う" name="chk2"/>
+ <check_box label="雇ってもらう" name="chk6"/>
+ <check_box label="グループ" name="chk3"/>
+ <check_box label="買う" name="chk4"/>
+ <check_box label="販売する" name="chk5"/>
+ <check_box label="雇う" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (ロード中...)
+ </line_editor>
+ <text name="Skills:">
+ スキル:
+ </text>
+ <check_box label="テクスチャ" name="schk0"/>
+ <check_box label="建築" name="schk1"/>
+ <check_box label="モデリング" name="schk3"/>
+ <check_box label="イベント計画" name="schk2"/>
+ <check_box label="スクリプト" name="schk4"/>
+ <check_box label="キャラクターのカスタマイズ" name="schk5"/>
+ <line_editor name="skills_edit">
+ (ロード中...)
+ </line_editor>
+ <text name="Languages:">
+ 言語:
+ </text>
+ <line_editor name="languages_edit">
+ (ロード中...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_notes.xml b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml
new file mode 100644
index 0000000000..4b4e0d5e4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="メモとプライバシー" name="panel_notes">
+ <text name="status_message" value="このアバターのプライベートメモ:"/>
+ <text name="status_message2" value="このアバターに次の許可を与える:"/>
+ <check_box label="自分のオンラインステータスを表示する" name="status_check"/>
+ <check_box label="世界地図で自分を探せるようにする" name="map_check"/>
+ <check_box label="自分のオブジェクトを編集・削除・取得できるようにする" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_pick.xml b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml
new file mode 100644
index 0000000000..0a20c04ad6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (掲載後更新)
+ </panel.string>
+ <line_editor name="pick_location">
+ ロード中...
+ </line_editor>
+ <button label="テレポート" name="teleport_btn"/>
+ <button label="地図に表示" name="show_on_map_btn"/>
+ <button label="場所を設定" name="set_to_curr_location_btn" tool_tip="現在地に設定"/>
+ <button label="ピックを保存" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_picks.xml b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml
new file mode 100644
index 0000000000..4cbfadd09d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="ピック" name="panel_picks">
+ <string name="no_picks" value="ピックなし"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Second Life のお気に入りの場所を紹介しましょう。
+ </text>
+ <button label="新規…" name="new_btn"/>
+ <button label="削除…" name="delete_btn"/>
+ <text name="picks_panel_text">
+ ロード中...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..5470dc6c82
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="プロフィール" name="panel_profile">
+ <string name="status_online">
+ オンライン中
+ </string>
+ <string name="status_offline">
+ オフライン中
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="なし"/>
+ <string name="no_group_text" value="なし"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="開発者"/>
+ <string name="FSSupp" value="サポート"/>
+ <string name="FSQualityAssurance" value="バグハンター"/>
+ <string name="FSGW" value="ゲートウェイ"/>
+ <text name="name_label" value="名前:"/>
+ <button label="名前:" name="set_name" tool_tip="表示名を設定"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(ロード中...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="ステータス不明"/>
+ <text name="label" value="Second Life 生年月日:"/>
+ <text name="label2" value="アカウント:"/>
+ <text name="partner_label" value="パートナー:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="グループ:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="グループに招待"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="詳細:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="アイテムを渡す:"/>
+ <text name="Give inventory" tool_tip="インベントリのアイテムをここにドロップしてこの人に渡します。">
+ インベントリのアイテムをここにドロップしてください。
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="地図上で見つける" label_selected="地図上で見つける" name="show_on_map_btn" tool_tip="住人を地図上で探す"/>
+ <button label="お金を払う" label_selected="お金を払う" name="pay" tool_tip="住人にお金を支払う"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="テレポートを送る" label_selected="テレポートを送る" name="teleport" tool_tip="住人にテレポートを送る"/>
+ <button label="インスタントメッセージ" label_selected="インスタントメッセージ" name="im" tool_tip="インスタントメッセージを開きます"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="フレンド登録" label_selected="フレンド登録" name="add_friend" tool_tip="フレンド登録を申し出ます"/>
+ <button label="ブロック" name="block" tool_tip="この住人をブロックする"/>
+ <button label="ブロック解除" name="unblock" tool_tip="この住人のブロックを解除する"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="検索に表示" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_web.xml b/indra/newview/skins/default/xui/ja/panel_profile_web.xml
new file mode 100644
index 0000000000..4f56a7e98d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="ロード時間:[TIME] 秒"/>
+ <line_editor name="url_edit">
+ (ロード中...)
+ </line_editor>
+ <flyout_button label="ロード" name="load" tool_tip="このプロフィールページを、組み込み Web ブラウザでロードします。">
+ <flyout_button.item label="ビューワ内のブラウザを開く" name="open_item"/>
+ <flyout_button.item label="外部ブラウザを開く" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Web プロフィールのポップアウト"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
index fb853c1925..c1080a7d7b 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="地形の上昇限度" name="terrain_raise_spin"/>
<spinner label="地形の下降限度" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形テクスチャ(512x512 の 24 bit .tga ファイル)
- </text>
+ 地形テクスチャ(1024x1024 の 24 bit .tga ファイル)
+ </text>
<text name="height_text_lbl">
1(低)
</text>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
index 04dfc0176d..f222a4d61a 100644
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
@@ -3,7 +3,7 @@
<button label="ディスクに保存" name="save_to_computer_btn"/>
<button label="持ち物に保存(L$[AMOUNT])" name="save_to_inventory_btn"/>
<button label="プロフィールフィードで共有する" name="save_to_profile_btn"/>
- <button label="Facebook で共有する" name="send_to_facebook_btn"/>
+ <button label="Facebook でシェア" name="send_to_facebook_btn"/>
<button label="Twitter で共有する" name="send_to_twitter_btn"/>
<button label="Flickr で共有する" name="send_to_flickr_btn"/>
<button label="メールにより送信" name="save_to_email_btn"/>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index b4bc36a800..d90772ab0a 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -186,7 +186,7 @@ LOD 係数: [LOD_FACTOR]
<string name="LoginFailedNoNetwork">
ネットワークエラー:接続を確立できませんでした。お使いのネットワーク接続をご確認ください。
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
ログインに失敗しました。
</string>
<string name="Quit">
@@ -356,6 +356,24 @@ support@secondlife.com にお問い合わせください。
<string name="TestingDisconnect">
ビューワの接続を切るテスト中
</string>
+ <string name="SocialFacebookConnecting">
+ Facebook に接続中...
+ </string>
+ <string name="SocialFacebookPosting">
+ 投稿中...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook から切断中...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Facebook への接続時のエラー
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Facebook への投稿時のエラー
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Facebook からの切断時のエラー
+ </string>
<string name="SocialFlickrConnecting">
Flickr に接続中...
</string>
@@ -673,9 +691,6 @@ support@secondlife.com にお問い合わせください。
<string name="GroupNameNone">
(なし)
</string>
- <string name="AvalineCaller">
- Avaline コール [ORDER]
- </string>
<string name="AssetErrorNone">
エラーなし
</string>
@@ -2577,9 +2592,21 @@ support@secondlife.com にお問い合わせください。
<string name="NoPicksClassifiedsText">
ピックやクラシファイド広告を作成していません。 作成するには、下にある「プラス」ボタンをクリックします。
</string>
+ <string name="NoPicksText">
+ ピックを作成していません。[新規] ボタンをクリックしてピックを作成する。
+ </string>
+ <string name="NoClassifiedsText">
+ クラシファイド広告を作成していません。[新規] ボタンをクリックしてクラシファイド広告を作成する。
+ </string>
<string name="NoAvatarPicksClassifiedsText">
ピック、またはクラシファイド広告がありません
</string>
+ <string name="NoAvatarPicksText">
+ ピックがありません
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ クラシファイド広告がありません
+ </string>
<string name="PicksClassifiedsLoadingText">
ローディング...
</string>
@@ -4557,6 +4584,9 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
<string name="share_alert">
インベントリからここにアイテムをドラッグします
</string>
+ <string name="facebook_post_success">
+ Facebook に投稿しました。
+ </string>
<string name="flickr_post_success">
Flickr に投稿しました。
</string>
diff --git a/indra/newview/skins/default/xui/pl/floater_picks.xml b/indra/newview/skins/default/xui/pl/floater_picks.xml
deleted file mode 100644
index a329e834db..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<floater name="floater_picks" title="Miejsca" />
diff --git a/indra/newview/skins/default/xui/pl/panel_me.xml b/indra/newview/skins/default/xui/pl/panel_me.xml
deleted file mode 100644
index 431929420a..0000000000
--- a/indra/newview/skins/default/xui/pl/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel label="Mój Profil" name="panel_me">
- <panel label="MIEJSCA" name="panel_picks" />
-</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
index f086a52dcd..2d4286334f 100644
--- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
@@ -7,7 +7,7 @@
<spinner label="Górny limit terenu" name="terrain_raise_spin" />
<spinner label="Dolny limit terenu" name="terrain_lower_spin" />
<text name="detail_texture_text">
- Tekstury terenu (512x512 / 1024x1024, 24 bitowy plik .tga)
+ Tekstury terenu (1024x1024, 24 bitowy plik .tga)
</text>
<text name="height_text_lbl">
1 (Nisko)
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index cf033df3c9..90d2d86c02 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -143,7 +143,7 @@ Wersja serwera głosu (Voice Server): [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Błąd sieci: Brak połączenia z siecią, sprawdź status swojego połączenia internetowego.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Logowanie nie powiodło się.
</string>
<string name="Quit">
@@ -596,9 +596,6 @@ Spróbuj zalogować się ponownie za minutę.
<string name="GroupNameNone">
(brak danych)
</string>
- <string name="AvalineCaller">
- Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Brak błędu
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
index c50d7dcda0..a43dec4e7b 100644
--- a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Gestos" name="check_gesture"/>
<check_box label="Landmarks" name="check_landmark"/>
<check_box label="Anotações" name="check_notecard"/>
- <check_box label="Meshes:" name="check_mesh"/>
+ <check_box label="Malhas" name="check_mesh"/>
<check_box label="Objetos" name="check_object"/>
<check_box label="Scripts" name="check_script"/>
<check_box label="Sons" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_picks.xml b/indra/newview/skins/default/xui/pt/floater_picks.xml
deleted file mode 100644
index 9766196319..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Destaques"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
index 6f39635240..90102023a3 100644
--- a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copiar para inventário
</floater.string>
- <text name="desc txt">
- Descrição:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Visualizar relação de aspecto
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa">
- <combo_item name="Unconstrained">
- Sem limites
- </combo_item>
- <combo_item name="1:1" tool_tip="Símbolo ou perfil RW do grupo">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] perfil">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Procurar anúncios classificados e marcos">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Sobre terrenos">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Perfis destacados">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Descartar" name="Discard"/>
- <button label="Salvar como" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descrição:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Visualizar relação de aspecto
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Descartar" name="Discard"/>
+ <button label="Salvar como" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_profile.xml b/indra/newview/skins/default/xui/pt/floater_profile.xml
new file mode 100644
index 0000000000..0327211d8f
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Perfil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interesses" name="panel_profile_interests"/>
+ <panel label="Destaques" name="panel_profile_picks"/>
+ <panel label="Anúncio" name="panel_profile_classifieds"/>
+ <panel label="Vida real" name="panel_profile_firstlife"/>
+ <panel label="Observações" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salvar alterações do perfil e fechar"/>
+ <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_snapshot.xml b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
index e3812ed708..89901b539f 100644
--- a/indra/newview/skins/default/xui/pt/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Enviando e-mail
</string>
+ <string name="facebook_progress_str">
+ Como publicar no Facebook
+ </string>
<string name="profile_progress_str">
Postando
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Salvo no computador
</string>
+ <string name="facebook_succeeded_str">
+ Imagem carregada
+ </string>
<string name="profile_succeeded_str">
Imagem carregada
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Salvo no computador!
</string>
+ <string name="facebook_failed_str">
+ Falha ao carregar a imagem na sua linha do tempo no Facebook.
+ </string>
<string name="profile_failed_str">
Falha ao carregar a imagem no feed do seu perfil.
</string>
diff --git a/indra/newview/skins/default/xui/pt/menu_name_field.xml b/indra/newview/skins/default/xui/pt/menu_name_field.xml
new file mode 100644
index 0000000000..2157de9813
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Exibir Cópia do Nome" name="copy_display"/>
+ <menu_item_call label="Copiar Nome do Agente" name="copy_name"/>
+ <menu_item_call label="Copiar Id do Agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index bd1185bdd2..733ec2c709 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -2673,6 +2673,9 @@ Selecione só um objeto.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
index 23e00bfc3a..7b27c811f5 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Cancelar" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_general.xml b/indra/newview/skins/default/xui/pt/panel_group_general.xml
index 64a7d13fdb..f6c6d11b87 100644
--- a/indra/newview/skins/default/xui/pt/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_general.xml
@@ -46,7 +46,7 @@ Para obter mais ajuda, passe o mouse sobre as opções.
<check_box label="Qualquer um pode entrar" name="open_enrollement" tool_tip="Controla a entrada de novos membros, com ou sem convite."/>
<check_box label="Taxa de inscrição" name="check_enrollment_fee" tool_tip="Controla a cobrança de uma taxa de associação ao grupo."/>
<spinner label="L$" left_delta="120" name="spin_enrollment_fee" tool_tip="Se a opção &apos;Taxa de associação&apos; estiver marcada, novos membros precisam pagar o valor definido para entrar no grupo." width="60"/>
- <combo_box name="group_mature_check" tool_tip="Os níveis de maturidade determinam o tipo de conteúdo e comportamento permitidos em um grupo" width="170">
+ <combo_box name="group_mature_check" tool_tip="Definir se o seu grupo contém informações classificadas como Moderado" width="170">
<combo_item name="select_mature">
- Selecione o nível de maturidade -
</combo_item>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..0490878507
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Desconhecido"/>
+ <button name="info_btn" tool_tip="Mais informações"/>
+ <button name="profile_btn" tool_tip="Ver perfil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_me.xml b/indra/newview/skins/default/xui/pt/panel_me.xml
deleted file mode 100644
index 281c886bd4..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Meu perfil" name="panel_me">
- <panel label="MEUS DESTAQUES" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml
index 2ef01841c5..ce50449b03 100644
--- a/indra/newview/skins/default/xui/pt/panel_people.xml
+++ b/indra/newview/skins/default/xui/pt/panel_people.xml
@@ -40,6 +40,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Todos"/>
+ <accordion_tab name="tab_suggested_friends" title="Pessoas que talvez você deseje adicionar"/>
</accordion>
</panel>
<panel label="GRUPOS" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classified.xml b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml
new file mode 100644
index 0000000000..b43a0ad9f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderado
+ </panel.string>
+ <panel.string name="type_pg">
+ Conteúdo Geral
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]-
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teletransporte, [MAP] mapa, [PROFILE] perfil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Ativado
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Desativado
+ </panel.string>
+ <panel.string name="location_notice">
+ (salvar para atualizar)
+ </panel.string>
+ <string name="publish_label">
+ Publicar
+ </string>
+ <string name="save_label">
+ Salvar
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Selecione uma imagem"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Localização:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo de conteúdo:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoria:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Data de criação:"/>
+ <text_editor name="creation_date" tool_tip="Data de criação" value="[date]"/>
+ <text name="price_for_listing_label" value="Preço do anúncio:"/>
+ <text_editor name="price_for_listing" tool_tip="Preço do anúncio.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Cliques:"/>
+ <text_editor name="click_through_text" tool_tip="Dados de click-through" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renovação automática:"/>
+ <text name="auto_renew" value="Ativado"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descrição:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Título:
+ </text>
+ <text name="description_label">
+ Descrição:
+ </text>
+ <text name="location_label">
+ Localização:
+ </text>
+ <text name="classified_location_edit">
+ Carregando...
+ </text>
+ <button label="Usar configuração local" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoria:"/>
+ <text name="content_type_label" value="Tipo de conteúdo:"/>
+ <icons_combo_box label="Conteúdo Geral" name="content_type_edit">
+ <icons_combo_box.item label="Conteúdo Moderado" name="mature_ci" value="Moderado"/>
+ <icons_combo_box.item label="Conteúdo Geral" name="pg_ci" value="Adequado para menores"/>
+ </icons_combo_box>
+ <check_box label="Renovar automaticamente todas as semanas" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Preço do anúncio:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Preço do anúncio." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teletransportar" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mapa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Editar" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..f8369954fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anúncio" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Nenhum classificado"/>
+ <button label="Novo..." name="new_btn"/>
+ <button label="Excluir..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Carregando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/floater_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml
index dfc539da66..0fb502e441 100644
--- a/indra/newview/skins/default/xui/it/floater_picks.xml
+++ b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Preferiti"/>
+<panel label="Perfil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_interests.xml b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml
new file mode 100644
index 0000000000..edf74115f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interesses" name="panel_profile_interests">
+ <text name="I Want To:">
+ Quero:
+ </text>
+ <check_box label="Crie" name="chk0"/>
+ <check_box label="Explore" name="chk1"/>
+ <check_box label="Encontrar" name="chk2"/>
+ <check_box label="Seja contratado" name="chk6"/>
+ <check_box label="Grupo" name="chk3"/>
+ <check_box label="Comprar" name="chk4"/>
+ <check_box label="Venda" name="chk5"/>
+ <check_box label="Contratar" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (carregando...)
+ </line_editor>
+ <text name="Skills:">
+ Habilidades:
+ </text>
+ <check_box label="Texturas" name="schk0"/>
+ <check_box label="Arquitetura" name="schk1"/>
+ <check_box label="Modelo" name="schk3"/>
+ <check_box label="Planejamento de evento" name="schk2"/>
+ <check_box label="Scripts" name="schk4"/>
+ <check_box label="Personagens personalizados" name="schk5"/>
+ <line_editor name="skills_edit">
+ (carregando...)
+ </line_editor>
+ <text name="Languages:">
+ Idiomas:
+ </text>
+ <line_editor name="languages_edit">
+ (carregando...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_notes.xml b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml
new file mode 100644
index 0000000000..499e371bb7
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anotações e Privacidade" name="panel_notes">
+ <text name="status_message" value="Notas particulares neste avatar:"/>
+ <text name="status_message2" value="Permitir que esse avatar:"/>
+ <check_box label="Ver quando eu estiver conectado" name="status_check"/>
+ <check_box label="Encontre-me no mapa-múndi" name="map_check"/>
+ <check_box label="Pegar, editar ou excluir objetos meus" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_pick.xml b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml
new file mode 100644
index 0000000000..2dd37b38f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (salvar para atualizar)
+ </panel.string>
+ <line_editor name="pick_location">
+ Carregando...
+ </line_editor>
+ <button label="Teletransportar" name="teleport_btn"/>
+ <button label="Mostrar no mapa" name="show_on_map_btn"/>
+ <button label="Definir Localização" name="set_to_curr_location_btn" tool_tip="Usar configuração local"/>
+ <button label="Salvar destaque" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml
new file mode 100644
index 0000000000..f9ead974dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Destaques" name="panel_picks">
+ <string name="no_picks" value="Nenhum"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Conte a todos sobre os seu lugares favoritos no Second Life.
+ </text>
+ <button label="Novo..." name="new_btn"/>
+ <button label="Excluir..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Carregando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..8723b1bf58
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Perfil" name="panel_profile">
+ <string name="status_online">
+ Atualmente Online
+ </string>
+ <string name="status_offline">
+ Atualmente Offline
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Nenhum"/>
+ <string name="no_group_text" value="Nenhum"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Desenvolvedor"/>
+ <string name="FSSupp" value="Suporte"/>
+ <string name="FSQualityAssurance" value="Caçador de Bug"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Nome:"/>
+ <button label="Nome:" name="set_name" tool_tip="Definir nome de tela"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(carregando...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status desconhecido"/>
+ <text name="label" value="Aniversário Second Life:"/>
+ <text name="label2" value="Conta:"/>
+ <text name="partner_label" value="Parceiro(a):"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Grupos:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Convidar para entrar no grupo"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Sobre:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Dar o item:"/>
+ <text name="Give inventory" tool_tip="Arraste e solte o item novo do inventário aqui para dá-los a esta pessoa.">
+ Arraste e solte o item novo do inventário aqui.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Localizar no mapa" label_selected="Localizar no mapa" name="show_on_map_btn" tool_tip="Localizar o Residente no mapa"/>
+ <button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pague em dinheiro para o Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Teletransportar?" label_selected="Teletransportar?" name="teleport" tool_tip="Oferecer teletransporte ao Residente"/>
+ <button label="Mensagem instantânea" label_selected="Mensagem instantânea" name="im" tool_tip="Abrir sessão de mensagem instantânea"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Adicionar amigo" label_selected="Adicionar amigo" name="add_friend" tool_tip="Oferecer amizade ao residente"/>
+ <button label="Bloquear" name="block" tool_tip="Bloquear este Residente"/>
+ <button label="Desbloquear" name="unblock" tool_tip="Desbloquear este Residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostrar nos resultados de busca" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_web.xml b/indra/newview/skins/default/xui/pt/panel_profile_web.xml
new file mode 100644
index 0000000000..0f556c7dad
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Carregar tempo: [TIME] segundos"/>
+ <line_editor name="url_edit">
+ (carregando..)
+ </line_editor>
+ <flyout_button label="Carregar" name="load" tool_tip="Carregar esta página de perfil com navegador embutido">
+ <flyout_button.item label="Abrir no visualizador do navegador" name="open_item"/>
+ <flyout_button.item label="Abrir no navegador externo" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Abra o perfil da web"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
index 74330a8946..1d312aeed9 100644
--- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite mais baixo do
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas de terreno (exige arquivos .tga 512x512, 24 bit)
- </text>
+ Texturas de terreno (exige arquivos .tga 1024x1024, 24 bit)
+ </text>
<text name="height_text_lbl">
1 (Baixo)
</text>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index c72a41fd3a..ae452d6a4d 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -47,7 +47,7 @@ Placa de vídeo: [GRAPHICS_CARD_VENDOR]
Placa gráfica: [GRAPHICS_CARD]
</string>
<string name="AboutDriver">
- Versão do driver de vídeo Windows: [GRAPHICS_CARD_VENDOR]
+ Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION]
</string>
<string name="AboutOGL">
Versão do OpenGL: [OPENGL_VERSION]
@@ -178,7 +178,7 @@ Versão do servidor de voz: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Erro de rede: Falha de conexão: verifique sua conexão à internet.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Falha do login.
</string>
<string name="Quit">
@@ -313,6 +313,24 @@ Aguarde um minuto antes que tentar logar-se novamente.
<string name="TestingDisconnect">
Teste de desconexão
</string>
+ <string name="SocialFacebookConnecting">
+ Conectando ao Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Publicando...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Desconectando do Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problema ao conectar ao Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problema ao publicar no Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problema ao desconectar do Facebook
+ </string>
<string name="SocialFlickrConnecting">
Conectando ao Flickr...
</string>
@@ -627,9 +645,6 @@ ser anexado às anotações.
<string name="GroupNameNone">
(nenhum)
</string>
- <string name="AvalineCaller">
- Interlocutor Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Nenhum erro
</string>
@@ -2517,9 +2532,21 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se
<string name="NoPicksClassifiedsText">
Você não criou nenhum Destaque ou Anúncio. Clique no botão &quot;+&quot; para criar um Destaque ou Anúncio.
</string>
+ <string name="NoPicksText">
+ Você não criou nenhuma Escolha. Clique em Novo Botão para criar um Escolher
+ </string>
+ <string name="NoClassifiedsText">
+ Você criou nenhum Anúncio. Clique em Novo Botão para criar um Classificado
+ </string>
<string name="NoAvatarPicksClassifiedsText">
O usuário não tem nenhum destaque ou anúncio
</string>
+ <string name="NoAvatarPicksText">
+ Usuário não tem escolha
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Usuário não tem anúncio
+ </string>
<string name="PicksClassifiedsLoadingText">
Carregando...
</string>
@@ -4433,6 +4460,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="inventory_folder_offered-im">
Pasta do inventário &apos;[ITEM_NAME]&apos; oferecida
</string>
+ <string name="facebook_post_success">
+ Você publicou no Facebook.
+ </string>
<string name="flickr_post_success">
Você publicou no Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
index 7c1d3b52c5..bf90d898f9 100644
--- a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Жесты" name="check_gesture"/>
<check_box label="Закладки" name="check_landmark"/>
<check_box label="Заметки" name="check_notecard"/>
- <check_box label="Меши" name="check_mesh"/>
+ <check_box label="Полисетки" name="check_mesh"/>
<check_box label="Объекты" name="check_object"/>
<check_box label="Скрипты" name="check_script"/>
<check_box label="Звуки" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_picks.xml b/indra/newview/skins/default/xui/ru/floater_picks.xml
deleted file mode 100644
index e0ae8d6f03..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Подборка"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
index 46d2a37503..e3921a75ac 100644
--- a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Копировать в инвентарь
</floater.string>
- <text name="desc txt">
- Описание:
- </text>
- <text name="dimensions">
- [WIDTH]пикселей x [HEIGHT]пикселей
- </text>
- <text name="aspect_ratio">
- Просмотр изображения с соотношением сторон
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон">
- <combo_item name="Unconstrained">
- Без ограничения
- </combo_item>
- <combo_item name="1:1" tool_tip="Символ группы или профиль в реальном мире">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Профиль для [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Реклама, поиск и закладки">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="О земле">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Профиль подборки">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Отменить" name="Discard"/>
- <button label="Сохранить как" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Описание:
+ </text>
+ <text name="dimensions">
+ [WIDTH]пикселей x [HEIGHT]пикселей
+ </text>
+ <text name="aspect_ratio">
+ Предварительный просмотр соотношения сторон
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Сбросить" name="Discard"/>
+ <button label="Сохранить как" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_profile.xml b/indra/newview/skins/default/xui/ru/floater_profile.xml
new file mode 100644
index 0000000000..6f8daf0a62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Профиль">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Веб" name="panel_profile_web"/>
+ <panel label="Круг интересов" name="panel_profile_interests"/>
+ <panel label="Подборка" name="panel_profile_picks"/>
+ <panel label="Объявление" name="panel_profile_classifieds"/>
+ <panel label="Реальная жизнь" name="panel_profile_firstlife"/>
+ <panel label="Примечания" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Сохранить изменения в профиле и закрыть"/>
+ <button label="Отменить" label_selected="Отменить" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
index 3ac8cb74b4..89a453d9cd 100644
--- a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
@@ -67,7 +67,7 @@
<combo_box.item label="Земля &gt; Посягательство &gt; Объекты или текстуры" name="Land__Encroachment__Objects_textures"/>
<combo_box.item label="Земля &gt; Посягательство &gt; Частицы" name="Land__Encroachment__Particles"/>
<combo_box.item label="Земля &gt; Посягательство &gt; Деревья/растения" name="Land__Encroachment__Trees_plants"/>
- <combo_box.item label="Нарушение правил игр на ловкость" name="Wagering_gambling"/>
+ <combo_box.item label="Нарушение игровых правил" name="Wagering_gambling"/>
<combo_box.item label="Другое" name="Other"/>
</combo_box>
<text name="abuser_name_title">
diff --git a/indra/newview/skins/default/xui/ru/floater_snapshot.xml b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
index 97de279b8f..a796d942f3 100644
--- a/indra/newview/skins/default/xui/ru/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Отправка письма
</string>
+ <string name="facebook_progress_str">
+ Публикация в Facebook
+ </string>
<string name="profile_progress_str">
Публикация
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Сохранение на компьютере
</string>
+ <string name="facebook_succeeded_str">
+ Изображение загружено
+ </string>
<string name="profile_succeeded_str">
Изображение отправлено
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Сохранено на компьютере!
</string>
+ <string name="facebook_failed_str">
+ Не удалось передать изображение на вашу хронику Facebook.
+ </string>
<string name="profile_failed_str">
Не удалось передать изображение в ваш профиль.
</string>
diff --git a/indra/newview/skins/default/xui/ru/menu_name_field.xml b/indra/newview/skins/default/xui/ru/menu_name_field.xml
new file mode 100644
index 0000000000..889f3c37ab
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Копировать отображаемое имя" name="copy_display"/>
+ <menu_item_call label="Копировать имя агента" name="copy_name"/>
+ <menu_item_call label="Копировать Id агента" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index bfcda798be..e75fd1fd82 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -2682,6 +2682,9 @@
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
index a2f06dbadf..ec457c4565 100644
--- a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
@@ -46,8 +46,8 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
- <button label="Отмена" name="cancel_btn"/>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Отменить" name="cancel_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
index 746da8d523..1e4d1346f7 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Сейчас у вас нет друзей по Facebook, которые также были бы жителями Second Life. Предложите своим друзьям по Facebook присоединиться к Second Life!"/>
+ <string name="facebook_friends_empty" value="Сейчас у вас нет друзей в Facebook, которые являются также жителями Second Life. Предложите своим друзьям в Facebook присоединиться к Second Life!"/>
<string name="facebook_friends_no_connected" value="Сейчас вы не подключены к Facebook. Перейдите на вкладку «Статус», чтобы подключиться и включить эту функцию."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Друзья по SL"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
index 143a57fec7..50296778ff 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
@@ -2,19 +2,19 @@
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Разрешение изображения">
<combo_box.item label="Текущее окно" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1200x630" name="1200x630"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
<combo_box name="filters_combobox" tool_tip="Фильтры изображений">
<combo_box.item label="Без фильтра" name="NoFilter"/>
</combo_box>
- <button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкните для обновления"/>
- <button label="Просмотр" name="big_preview_btn" tool_tip="Щелкните для смены вида"/>
+ <button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкнуть для обновления"/>
+ <button label="Предпросмотр" name="big_preview_btn" tool_tip="Щелкнуть для смены вида"/>
<text name="caption_label">
Комментарий (не обязательно):
</text>
<button label="Опубликовать" name="post_photo_btn"/>
- <button label="Отмена" name="cancel_photo_btn"/>
+ <button label="Отменить" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
index 7d0917a43a..a7fadca059 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_place">
<text name="place_caption_label">
- Напишите о том, где вы:
+ Сообщите, где вы находитесь:
</text>
<check_box initial_value="false" label="Включить вид места сверху" name="add_place_view_cb"/>
<button label="Опубликовать" name="post_place_btn"/>
- <button label="Отмена" name="cancel_place_btn"/>
+ <button label="Отменить" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
index c651a8087c..826ac6a08c 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
<string name="facebook_connected" value="Вы подключились к Facebook как:"/>
- <string name="facebook_disconnected" value="Не подключено к Facebook"/>
+ <string name="facebook_disconnected" value="Нет подключения к Facebook"/>
<text name="account_caption_label">
- Не подключено к Facebook.
+ Нет подключения к Facebook.
</text>
<panel name="panel_buttons">
- <button label="Подключение..." name="connect_btn"/>
- <button label="Отключить" name="disconnect_btn"/>
+ <button label="Соединение..." name="connect_btn"/>
+ <button label="Разъединить" name="disconnect_btn"/>
<text name="account_learn_more_label">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 О публикации в Facebook]
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Узнать о публикации в Facebook]
</text>
</panel>
<text name="status_caption_label">
О чем вы думаете?
</text>
<button label="Опубликовать" name="post_status_btn"/>
- <button label="Отмена" name="cancel_status_btn"/>
+ <button label="Отменить" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..3408969d09
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Неизвестно"/>
+ <button name="info_btn" tool_tip="Больше информации"/>
+ <button name="profile_btn" tool_tip="Посмотреть профиль"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_me.xml b/indra/newview/skins/default/xui/ru/panel_me.xml
deleted file mode 100644
index 21a125af87..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Мой профиль" name="panel_me">
- <panel label="МОЯ ПОДБОРКА" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
index 5e3de180f9..331ba889d8 100644
--- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
@@ -14,7 +14,7 @@
<label name="favorites_bar_label" tool_tip="Перетаскивайте сюда закладки, чтобы было удобнее переходить в любимые места в Second Life!">
Избранное
</label>
- <more_button name="&gt;&gt;" tool_tip="Показать больше избранного">
+ <more_button name="&gt;&gt;" tool_tip="Показать больше избранного" width="60">
Больше ▼
</more_button>
</favorites_bar>
diff --git a/indra/newview/skins/default/xui/ru/panel_people.xml b/indra/newview/skins/default/xui/ru/panel_people.xml
index 0812eb7433..8170c8d26f 100644
--- a/indra/newview/skins/default/xui/ru/panel_people.xml
+++ b/indra/newview/skins/default/xui/ru/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Онлайн"/>
<accordion_tab name="tab_all" title="Все"/>
+ <accordion_tab name="tab_suggested_friends" title="С кем вы можете подружиться"/>
</accordion>
</panel>
<panel label="ГРУППЫ" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classified.xml b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml
new file mode 100644
index 0000000000..2d3ed685c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Умеренная
+ </panel.string>
+ <panel.string name="type_pg">
+ Общий контент
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ Телепорт [TELEPORT], карта [MAP], профиль [PROFILE]
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Включен
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Отключен
+ </panel.string>
+ <panel.string name="location_notice">
+ (будет обновлено после сохранения)
+ </panel.string>
+ <string name="publish_label">
+ Опубликовать
+ </string>
+ <string name="save_label">
+ Сохранить
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Щелкнуть для выбора изображения"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Местоположение:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Тип контента:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Категория:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Дата создания:"/>
+ <text_editor name="creation_date" tool_tip="Дата создания" value="[date]"/>
+ <text name="price_for_listing_label" value="Стоимость размещения:"/>
+ <text_editor name="price_for_listing" tool_tip="Цена за размещение.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Клики:"/>
+ <text_editor name="click_through_text" tool_tip="Информация о переходах" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Автоматическое продление:"/>
+ <text name="auto_renew" value="Включен"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Описание:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Название:
+ </text>
+ <text name="description_label">
+ Описание:
+ </text>
+ <text name="location_label">
+ Местоположение:
+ </text>
+ <text name="classified_location_edit">
+ загрузка...
+ </text>
+ <button label="Установить в текущее местоположение" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Категория:"/>
+ <text name="content_type_label" value="Тип контента:"/>
+ <icons_combo_box label="Общий контент" name="content_type_edit">
+ <icons_combo_box.item label="Умеренный контент" name="mature_ci" value="Возрастной"/>
+ <icons_combo_box.item label="Общий контент" name="pg_ci" value="C разрешения родителей"/>
+ </icons_combo_box>
+ <check_box label="Автоматическое обновление каждую неделю" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Стоимость размещения:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Цена за размещение." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Телепорт" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Карта" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Редактировать" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Отменить" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..fac494682a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Объявление" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Нет рекламы"/>
+ <button label="Новый..." name="new_btn"/>
+ <button label="Удалить..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Загрузка...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..f5ac5e906a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Профиль" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_interests.xml b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml
new file mode 100644
index 0000000000..ba1c3d0357
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Круг интересов" name="panel_profile_interests">
+ <text name="I Want To:">
+ Я собираюсь:
+ </text>
+ <check_box label="Построить" name="chk0"/>
+ <check_box label="Просмотреть" name="chk1"/>
+ <check_box label="Встретить" name="chk2"/>
+ <check_box label="Получить работу" name="chk6"/>
+ <check_box label="Группа" name="chk3"/>
+ <check_box label="Купить" name="chk4"/>
+ <check_box label="Продать" name="chk5"/>
+ <check_box label="Нанять" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (загрузка…)
+ </line_editor>
+ <text name="Skills:">
+ Навыки:
+ </text>
+ <check_box label="Текстуры" name="schk0"/>
+ <check_box label="Архитектура" name="schk1"/>
+ <check_box label="Моделирование" name="schk3"/>
+ <check_box label="Планирование мероприятия" name="schk2"/>
+ <check_box label="Создавать сценарии" name="schk4"/>
+ <check_box label="Пользовательские символы" name="schk5"/>
+ <line_editor name="skills_edit">
+ (загрузка…)
+ </line_editor>
+ <text name="Languages:">
+ Языки:
+ </text>
+ <line_editor name="languages_edit">
+ (загрузка…)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_notes.xml b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml
new file mode 100644
index 0000000000..41117c743a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Примечания и конфиденциальность" name="panel_notes">
+ <text name="status_message" value="Личные заметки об этом аватаре:"/>
+ <text name="status_message2" value="Разрешить этому аватару:"/>
+ <check_box label="Смотреть, когда я в сети" name="status_check"/>
+ <check_box label="Найти меня на карте мира" name="map_check"/>
+ <check_box label="Редактировать, удалять или брать мои объекты" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_pick.xml b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml
new file mode 100644
index 0000000000..a2ff5710ea
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (будет обновлено после сохранения)
+ </panel.string>
+ <line_editor name="pick_location">
+ Загрузка...
+ </line_editor>
+ <button label="Телепорт" name="teleport_btn"/>
+ <button label="Показать на карте" name="show_on_map_btn"/>
+ <button label="Указать местоположение" name="set_to_curr_location_btn" tool_tip="Установить в текущее местоположение"/>
+ <button label="Сохранить подборку" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_picks.xml b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml
new file mode 100644
index 0000000000..227b3f82b8
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Подборка" name="panel_picks">
+ <string name="no_picks" value="Нет подборки"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Сообщить всем о ваших избранных службах в Second Life.
+ </text>
+ <button label="Новый..." name="new_btn"/>
+ <button label="Удалить..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Загрузка...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..e7a66ba29e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Профиль" name="panel_profile">
+ <string name="status_online">
+ В настоящее время в режиме онлайн
+ </string>
+ <string name="status_offline">
+ В настоящее время в режиме оффлайн
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Никто"/>
+ <string name="no_group_text" value="Никто"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Разработчик"/>
+ <string name="FSSupp" value="Поддержка"/>
+ <string name="FSQualityAssurance" value="Отладчик"/>
+ <string name="FSGW" value="Межсетевой интерфейс"/>
+ <text name="name_label" value="Имя:"/>
+ <button label="Имя:" name="set_name" tool_tip="Задать отображаемое имя"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(загрузка…)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Статус неизвестен"/>
+ <text name="label" value="Дата рождения в Second Life:"/>
+ <text name="label2" value="Аккаунт:"/>
+ <text name="partner_label" value="Партнер:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Группы:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Пригласить в группу"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="О нас:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Передать вещь:"/>
+ <text name="Give inventory" tool_tip="Сбросить вещи из инвентаря здесь для передачи их этому игроку.">
+ Сбросить вещь из инвентаря здесь.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Найти на карте" label_selected="Найти на карте" name="show_on_map_btn" tool_tip="Найти жителя на карте"/>
+ <button label="Оплатить" label_selected="Оплатить" name="pay" tool_tip="Выплатить деньги резиденту"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Предложить телепорт" label_selected="Предложить телепорт" name="teleport" tool_tip="Предложить телепорт этому жителю"/>
+ <button label="Мгновенное сообщение" label_selected="Мгновенное сообщение" name="im" tool_tip="Начать сеанс IM"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Добавить друга" label_selected="Добавить друга" name="add_friend" tool_tip="Предложить дружбу этому жителю"/>
+ <button label="Заблокировать" name="block" tool_tip="Заблокировать этого жителя"/>
+ <button label="Разблокировать" name="unblock" tool_tip="Разблокировать этого жителя"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Показать в поиске" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_web.xml b/indra/newview/skins/default/xui/ru/panel_profile_web.xml
new file mode 100644
index 0000000000..18a17e2586
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Веб" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Время загрузки: [TIME] секунд"/>
+ <line_editor name="url_edit">
+ (загрузка…)
+ </line_editor>
+ <flyout_button label="Загрузить" name="load" tool_tip="Загрузить эту страницу с профилем с помощью встроенного веб-браузера.">
+ <flyout_button.item label="Открыть в просмотрщике браузера" name="open_item"/>
+ <flyout_button.item label="Открыть во внешнем браузере" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Всплывающий веб-профиль"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
index af25565226..76b4f513a8 100644
--- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Верх. точка ландшафта" name="terrain_raise_spin"/>
<spinner label="Ниж. точка ландшафта" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Текстуры ландшафта (требования: 512x512, 24-битные, TGA)
- </text>
+ Текстуры ландшафта (требования: 1024x1024, 24-битные, TGA)
+ </text>
<text name="height_text_lbl">
1 (Низ)
</text>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index ee2dcfe9cc..61d836a2d1 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -187,7 +187,7 @@ SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
<string name="LoginFailedNoNetwork">
Ошибка сети: не удалось установить соединение. Проверьте подключение к сети.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Ошибка входа.
</string>
<string name="Quit">
@@ -357,6 +357,24 @@ support@secondlife.com.
<string name="TestingDisconnect">
Тестирование отключения клиента
</string>
+ <string name="SocialFacebookConnecting">
+ Подключение к Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Публикация...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Отключение от Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Проблема с подключением к Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Проблемы при публикации в Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Проблема с отключением от Facebook
+ </string>
<string name="SocialFlickrConnecting">
Подключение к Flickr...
</string>
@@ -671,9 +689,6 @@ support@secondlife.com.
<string name="GroupNameNone">
(нет)
</string>
- <string name="AvalineCaller">
- [ORDER] абонента Avaline
- </string>
<string name="AssetErrorNone">
Ошибок нет
</string>
@@ -2576,9 +2591,21 @@ support@secondlife.com.
<string name="NoPicksClassifiedsText">
Вы не создали подборки или рекламы. Нажмите кнопку со знаком «плюс» ниже, чтобы создать подборку или рекламу
</string>
+ <string name="NoPicksText">
+ Вы не сделали никакой подборки. Нажмите кнопку Создать, чтобы сделать подборку.
+ </string>
+ <string name="NoClassifiedsText">
+ Вы не сделали никакой рекламы. Нажмите кнопку Создать, чтобы сделать рекламу.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
У жителя нет подборки или рекламы
</string>
+ <string name="NoAvatarPicksText">
+ У пользователя нет подборки
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ У пользователя нет объявлений
+ </string>
<string name="PicksClassifiedsLoadingText">
Загрузка...
</string>
@@ -4553,6 +4580,9 @@ support@secondlife.com.
<string name="share_alert">
Перетаскивайте вещи из инвентаря сюда
</string>
+ <string name="facebook_post_success">
+ Вы опубликовали сообщение в Facebook.
+ </string>
<string name="flickr_post_success">
Вы опубликовали сообщение в Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/tr/floater_facebook.xml b/indra/newview/skins/default/xui/tr/floater_facebook.xml
index 656a4a81c9..d8cbd84ed1 100644
--- a/indra/newview/skins/default/xui/tr/floater_facebook.xml
+++ b/indra/newview/skins/default/xui/tr/floater_facebook.xml
@@ -3,7 +3,7 @@
<tab_container name="tabs">
<panel label="DURUM" name="panel_facebook_status"/>
<panel label="FOTOĞRAF" name="panel_facebook_photo"/>
- <panel label="KONUMA GİRİŞ YAPIN" name="panel_facebook_place"/>
+ <panel label="GİRİŞ YAP" name="panel_facebook_place"/>
<panel label="ARKADAŞLAR" name="panel_facebook_friends"/>
</tab_container>
<text name="connection_error_text">
diff --git a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
index accb1ed71c..caa8497d3a 100644
--- a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Mimikler" name="check_gesture"/>
<check_box label="Yer İmleri" name="check_landmark"/>
<check_box label="Not Kartları" name="check_notecard"/>
- <check_box label="Örgüler" name="check_mesh"/>
+ <check_box label="Ağlar" name="check_mesh"/>
<check_box label="Nesneler" name="check_object"/>
<check_box label="Komut Dosyaları" name="check_script"/>
<check_box label="Sesler" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_picks.xml b/indra/newview/skins/default/xui/tr/floater_picks.xml
deleted file mode 100644
index 5aee6ae091..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Seçimler"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
index 8302c62070..8ba9123545 100644
--- a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Envantere Kopyala
</floater.string>
- <text name="desc txt">
- Açıklama:
- </text>
- <text name="dimensions">
- [WIDTH] pks x [HEIGHT] pks
- </text>
- <text name="aspect_ratio">
- En boy oranını önizle
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle">
- <combo_item name="Unconstrained">
- Kısıtsız
- </combo_item>
- <combo_item name="1:1" tool_tip="Grup işaretleri veya Real World profili">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] profili">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="İlanlar ve arama listeleri, yer imleri">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Arazi hakkında">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Profil seçmeleri">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="Tamam" name="Keep"/>
- <button label="At" name="Discard"/>
- <button label="Farklı Kaydet" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Açıklama:
+ </text>
+ <text name="dimensions">
+ [WIDTH]pks x [HEIGHT]pks
+ </text>
+ <text name="aspect_ratio">
+ En boy oranını önizle
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="Tamam" name="Keep"/>
+ <button label="At" name="Discard"/>
+ <button label="Farklı Kaydet" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_profile.xml b/indra/newview/skins/default/xui/tr/floater_profile.xml
new file mode 100644
index 0000000000..bb158ddf66
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="İlgi alanları" name="panel_profile_interests"/>
+ <panel label="Favoriler" name="panel_profile_picks"/>
+ <panel label="İlan" name="panel_profile_classifieds"/>
+ <panel label="Gerçek Hayat" name="panel_profile_firstlife"/>
+ <panel label="Notlar" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="Tamam" name="ok_btn" tool_tip="Değişiklikleri profile kaydet ve kapat"/>
+ <button label="İptal Et" label_selected="İptal Et" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_snapshot.xml b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
index be6c58e8cf..8496194700 100644
--- a/indra/newview/skins/default/xui/tr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
E-posta Gönderiliyor
</string>
+ <string name="facebook_progress_str">
+ Facebook&apos;ta yayınlanıyor
+ </string>
<string name="profile_progress_str">
Yayınlanıyor
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Bilgisayara Kaydediliyor
</string>
+ <string name="facebook_succeeded_str">
+ Görüntü yüklendi
+ </string>
<string name="profile_succeeded_str">
Görüntü yüklendi
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Bilgisayara Kaydedildi!
</string>
+ <string name="facebook_failed_str">
+ Görüntü Facebook zaman tünelinize yüklenemedi.
+ </string>
<string name="profile_failed_str">
Görüntü Profil Akışınıza yüklenemedi.
</string>
diff --git a/indra/newview/skins/default/xui/tr/menu_name_field.xml b/indra/newview/skins/default/xui/tr/menu_name_field.xml
new file mode 100644
index 0000000000..b1afd737c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Görünen Adı Kopyala" name="copy_display"/>
+ <menu_item_call label="Aracı Adını Kopyala" name="copy_name"/>
+ <menu_item_call label="Aracı Kimliğini Kopyala" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 5403a78f22..17d2969d19 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -2682,6 +2682,9 @@ Daha küçük bir arazi parçası seçmeyi deneyin.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
index fc444f21f6..78c34a3ac0 100644
--- a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="İptal Et" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
index 8184d6d7cf..edbe87d74c 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Şu an için aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızı bugün Second Life&apos;a katılmaya davet edin!"/>
+ <string name="facebook_friends_empty" value="Şu anda aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızdan bugün Second Life&apos;a katılmalarını isteyin!"/>
<string name="facebook_friends_no_connected" value="Şu anda Facebook&apos;a bağlı değilsiniz. Bağlanmak ve bu özelliği etkinleştirmek için lütfen Durum sekmesine gidin."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="SL arkadaşları"/>
<accordion_tab name="tab_suggested_friends" title="Bu kişileri SL arkadaşları olarak ekle"/>
</accordion>
<text name="facebook_friends_status">
- Facebook&apos;a bağlanılmadı.
+ Facebook&apos;a bağlanılamadı.
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
index d772aff937..e3150f258d 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Görüntü çözünürlüğü">
- <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
+ <combo_box.item label="Geçerli Pencere" name="CurrentWindow"/>
<combo_box.item label="640x480" name="640x480"/>
<combo_box.item label="800x600" name="800x600"/>
<combo_box.item label="1024x768" name="1024x768"/>
@@ -11,10 +11,10 @@
<combo_box.item label="Filtre Yok" name="NoFilter"/>
</combo_box>
<button label="Yenile" name="new_snapshot_btn" tool_tip="Yenilemek için tıklayın"/>
- <button label="Önizleme" name="big_preview_btn" tool_tip="Önizleme ayarları arasında geçiş yapmak için tıklayın"/>
+ <button label="Önizleme" name="big_preview_btn" tool_tip="Önizlemeye geçmek için tıklayın"/>
<text name="caption_label">
Yorum (isteğe bağlı):
</text>
<button label="Yayınla" name="post_photo_btn"/>
- <button label="İptal" name="cancel_photo_btn"/>
+ <button label="İptal Et" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
index 85b401a1a0..96c34d03d0 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
@@ -5,5 +5,5 @@
</text>
<check_box initial_value="false" label="Konumun üstten görünümünü ekle" name="add_place_view_cb"/>
<button label="Yayınla" name="post_place_btn"/>
- <button label="İptal" name="cancel_place_btn"/>
+ <button label="İptal Et" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
index e6feff5949..f5dba088de 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
<string name="facebook_connected" value="Facebook&apos;a şu kimlikle bağlandınız:"/>
- <string name="facebook_disconnected" value="Facebook&apos;a bağlanılmadı"/>
+ <string name="facebook_disconnected" value="Facebook&apos;a bağlanılamadı"/>
<text name="account_caption_label">
- Facebook&apos;a bağlanılmadı.
+ Facebook&apos;a bağlanılamadı.
</text>
<panel name="panel_buttons">
<button label="Bağlan..." name="connect_btn"/>
@@ -13,8 +13,8 @@
</text>
</panel>
<text name="status_caption_label">
- Ne düşünüyorsunuz?
+ Aklınızdan ne geçiyor?
</text>
<button label="Yayınla" name="post_status_btn"/>
- <button label="İptal" name="cancel_status_btn"/>
+ <button label="İptal Et" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_general.xml b/indra/newview/skins/default/xui/tr/panel_group_general.xml
index c666778c69..5578b36f3f 100644
--- a/indra/newview/skins/default/xui/tr/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_general.xml
@@ -45,7 +45,7 @@ Daha fazla yardım edinmek için farenizi seçeneklerin üzerine getirin.
<check_box label="Herkes katılabilir" name="open_enrollement" tool_tip="Bu grubun davet edilmeden yeni üyelerin katılmasına imkan tanıyıp tanımayacağını belirler."/>
<check_box label="Katılma ücreti" name="check_enrollment_fee" tool_tip="Bu gruba katılmak için bir kayıt ücretinin gerekip gerekmeyeceğini belirler"/>
<spinner label="L$" name="spin_enrollment_fee" tool_tip="Kayıt Ücreti işaretlendiğinde yeni üyeler gruba katılmak için bu ücreti ödemelidir."/>
- <combo_box name="group_mature_check" tool_tip="Erişkinlik dereceleri bir grupta izin verilen içerik ve davranış türlerini belirler">
+ <combo_box name="group_mature_check" tool_tip="Grubunuzun Orta olarak sınıflandırılmış bilgiler içerip içermeyeceğini belirler">
<combo_item name="select_mature">
- Erişkinlik seviyesini seçin -
</combo_item>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..0ed905ed35
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Bilinmiyor"/>
+ <button name="info_btn" tool_tip="Ek bilgi"/>
+ <button name="profile_btn" tool_tip="Profili görüntüle"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_me.xml b/indra/newview/skins/default/xui/tr/panel_me.xml
deleted file mode 100644
index d9e79d171c..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Profilim" name="panel_me">
- <panel label="SEÇTİKLERİM" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
index 8d43e3fb5a..ae9bc33bfa 100644
--- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
@@ -14,7 +14,7 @@
<label name="favorites_bar_label" tool_tip="Second Life içerisinde sık kullandığınız yerlere hızla erişmek için Yer İmlerini buraya sürükleyin!">
Favoriler Çubuğu
</label>
- <more_button name="&gt;&gt;" tool_tip="Favorilerimden daha çok göster">
+ <more_button name="&gt;&gt;" tool_tip="Favorilerimden daha çok göster" width="65">
Daha Fazla ▼
</more_button>
</favorites_bar>
diff --git a/indra/newview/skins/default/xui/tr/panel_people.xml b/indra/newview/skins/default/xui/tr/panel_people.xml
index 25d29fcbb5..acbcd2a544 100644
--- a/indra/newview/skins/default/xui/tr/panel_people.xml
+++ b/indra/newview/skins/default/xui/tr/panel_people.xml
@@ -40,6 +40,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Çevrimiçi"/>
<accordion_tab name="tab_all" title="Tümü"/>
+ <accordion_tab name="tab_suggested_friends" title="Arkadaş olmak isteyebileceğiniz kişiler"/>
</accordion>
</panel>
<panel label="GRUPLAR" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classified.xml b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml
new file mode 100644
index 0000000000..805de24c11
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Orta
+ </panel.string>
+ <panel.string name="type_pg">
+ Genel İçerik
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] ışınlanma, [MAP] harita, [PROFILE] profil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Etkin
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Devre dışı
+ </panel.string>
+ <panel.string name="location_notice">
+ (kaydedildikten sonra güncellenir)
+ </panel.string>
+ <string name="publish_label">
+ Yayınla
+ </string>
+ <string name="save_label">
+ Kaydet
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Bir görüntü seçmek için tıklayın"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Konum:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="İçerik Türü:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Kategori:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Oluşturma tarihi:"/>
+ <text_editor name="creation_date" tool_tip="Oluşturma tarihi" value="[date]"/>
+ <text name="price_for_listing_label" value="İlan fiyatı:"/>
+ <text_editor name="price_for_listing" tool_tip="İlan fiyatı.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Tıklama sayısı:"/>
+ <text_editor name="click_through_text" tool_tip="Tıklama verileri" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Otomatik yenileme:"/>
+ <text name="auto_renew" value="Etkin"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Açıklama:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Başlık:
+ </text>
+ <text name="description_label">
+ Açıklama:
+ </text>
+ <text name="location_label">
+ Konum:
+ </text>
+ <text name="classified_location_edit">
+ yükleniyor...
+ </text>
+ <button label="Geçerli Konuma Ayarla" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Kategori:"/>
+ <text name="content_type_label" value="İçerik türü:"/>
+ <icons_combo_box label="Genel İçerik" name="content_type_edit">
+ <icons_combo_box.item label="Orta İçerik" name="mature_ci" value="Yetişkin"/>
+ <icons_combo_box.item label="Genel İçerik" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Her hafta otomatik yenile" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="İlan fiyatı:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="İlan fiyatı." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Işınlanma" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Harita" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Düzenle" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="İptal Et" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..0edae1ab2a
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="İlan" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="İlan Yok"/>
+ <button label="Yeni..." name="new_btn"/>
+ <button label="Sil..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Yükleniyor...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..0f65090209
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_interests.xml b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml
new file mode 100644
index 0000000000..b068aa3dad
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="İlgi alanları" name="panel_profile_interests">
+ <text name="I Want To:">
+ Şunu Yapmak İstiyorum:
+ </text>
+ <check_box label="İnşa Et" name="chk0"/>
+ <check_box label="Keşfet" name="chk1"/>
+ <check_box label="Tanış" name="chk2"/>
+ <check_box label="İşe Gir" name="chk6"/>
+ <check_box label="Gruplandır" name="chk3"/>
+ <check_box label="Satın Al" name="chk4"/>
+ <check_box label="Sat" name="chk5"/>
+ <check_box label="İşe Al" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (yükleniyor...)
+ </line_editor>
+ <text name="Skills:">
+ Beceriler:
+ </text>
+ <check_box label="Dokular" name="schk0"/>
+ <check_box label="Mimari" name="schk1"/>
+ <check_box label="Modelleme" name="schk3"/>
+ <check_box label="Etkinlik Planlama" name="schk2"/>
+ <check_box label="Kodlama" name="schk4"/>
+ <check_box label="Özel Karakterler" name="schk5"/>
+ <line_editor name="skills_edit">
+ (yükleniyor...)
+ </line_editor>
+ <text name="Languages:">
+ Diller:
+ </text>
+ <line_editor name="languages_edit">
+ (yükleniyor...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_notes.xml b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml
new file mode 100644
index 0000000000..fff75dd685
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notlar ve Gizlilik" name="panel_notes">
+ <text name="status_message" value="Bu avatar ile ilgili özel notlar:"/>
+ <text name="status_message2" value="Bu avatar için şunlara izin ver:"/>
+ <check_box label="Çevrimiçi olduğumu görme" name="status_check"/>
+ <check_box label="Beni dünya haritasında bulma" name="map_check"/>
+ <check_box label="Nesnelerimi düzenleme, silme veya alma" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_pick.xml b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml
new file mode 100644
index 0000000000..d42c1eff7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (kaydedildikten sonra güncellenir)
+ </panel.string>
+ <line_editor name="pick_location">
+ Yükleniyor...
+ </line_editor>
+ <button label="Işınlanma" name="teleport_btn"/>
+ <button label="Haritada Göster" name="show_on_map_btn"/>
+ <button label="Konumu Ayarla" name="set_to_curr_location_btn" tool_tip="Geçerli Konuma Ayarla"/>
+ <button label="Favoriyi Kaydet" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_picks.xml b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml
new file mode 100644
index 0000000000..7222a2fc2e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Favoriler" name="panel_picks">
+ <string name="no_picks" value="Favori Yok"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Second Life&apos;ta favori yerlerinizi herkese anlatın!
+ </text>
+ <button label="Yeni..." name="new_btn"/>
+ <button label="Sil..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Yükleniyor...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..00e81d005e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Şu Anda Çevrimiçi
+ </string>
+ <string name="status_offline">
+ Şu Anda Çevrimdışı
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Yok"/>
+ <string name="no_group_text" value="Yok"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Geliştirici"/>
+ <string name="FSSupp" value="Destek"/>
+ <string name="FSQualityAssurance" value="Böcek bilimci"/>
+ <string name="FSGW" value="Ağ geçidi"/>
+ <text name="name_label" value="Ad:"/>
+ <button label="Ad:" name="set_name" tool_tip="Görünen Adı Ayarla"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(yükleniyor...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Durum Bilinmiyor"/>
+ <text name="label" value="Second Life Doğum Tarihi:"/>
+ <text name="label2" value="Hesap:"/>
+ <text name="partner_label" value="Ortak:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruplar:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Gruba Davet Et"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Hakkında:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Öğe ver:"/>
+ <text name="Give inventory" tool_tip="Envanter öğelerini bu kişiye vermek için buraya bırakın.">
+ Envanter öğesini buraya bırakın.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Haritada Bul" label_selected="Haritada Bul" name="show_on_map_btn" tool_tip="Sakini haritada bul"/>
+ <button label="Öde" label_selected="Öde" name="pay" tool_tip="Sakine para öde"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Işınlanma Teklif Et" label_selected="Işınlanma Teklif Et" name="teleport" tool_tip="Sakine ışınlanma teklif et"/>
+ <button label="Anlık İleti" label_selected="Anlık İleti" name="im" tool_tip="Anlık ileti oturumu aç"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Arkadaş Ekle" label_selected="Arkadaş Ekle" name="add_friend" tool_tip="Sakine arkadaşlık teklif et"/>
+ <button label="Engelle" name="block" tool_tip="Bu Sakini engelle"/>
+ <button label="Engellemeyi Kaldır" name="unblock" tool_tip="Bu Sakinin engellemesini kaldır"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Aramada göster" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_web.xml b/indra/newview/skins/default/xui/tr/panel_profile_web.xml
new file mode 100644
index 0000000000..265b1fee7e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Yükleme Süresi: [TIME] saniye"/>
+ <line_editor name="url_edit">
+ (yükleniyor..)
+ </line_editor>
+ <flyout_button label="Yükle" name="load" tool_tip="Bu profil sayfasını tümleşik web tarayıcı ile yükleyin.">
+ <flyout_button.item label="Görüntüleyici içindeki tarayıcıda aç" name="open_item"/>
+ <flyout_button.item label="Dış tarayıcıda aç" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Açılır web profili"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
index 3226ee008e..e25047301d 100644
--- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Yüzey Yükslt. Limiti" name="terrain_raise_spin"/>
<spinner label="Yüzey Alçatma Limiti" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir)
- </text>
+ Yüzey Dokuları (1024x1024, 24 bit .tga dosyalar gerektirir)
+ </text>
<text name="height_text_lbl">
1 (Düşük)
</text>
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index 982de76a5b..e709a4c5d6 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -187,7 +187,7 @@ Ses Sunucusu Sürümü: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Ağ hatası: Bağlantı kurulamadı, lütfen ağ bağlantınızı kontrol edin.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Oturum açılamadı.
</string>
<string name="Quit">
@@ -357,6 +357,24 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="TestingDisconnect">
Görüntüleyici bağlantısının kesilmesi test ediliyor
</string>
+ <string name="SocialFacebookConnecting">
+ Facebook ile bağlantı kuruluyor...
+ </string>
+ <string name="SocialFacebookPosting">
+ Yayınlanıyor...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook bağlantısı kesiliyor...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Facebook ile bağlantı kurulurken sorun oluştu
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Facebook&apos;ta yayınlarken sorun oluştu
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Facebook bağlantısı kesilirken sorun oluştu
+ </string>
<string name="SocialFlickrConnecting">
Flickr bağlantısı kuruluyor...
</string>
@@ -671,9 +689,6 @@ kartlarına eklenebilir.
<string name="GroupNameNone">
(hiçbiri)
</string>
- <string name="AvalineCaller">
- Avaline Arayanı [ORDER]
- </string>
<string name="AssetErrorNone">
Hata yok
</string>
@@ -2576,9 +2591,21 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin
<string name="NoPicksClassifiedsText">
Herhangi bir Seçme veya İlan oluşturmadınız. Bir Seçme veya İlan oluşturmak için aşağıdaki Artı düğmesine tıklayın.
</string>
+ <string name="NoPicksText">
+ Herhangi bir Favori oluşturmadınız. Bir Favori oluşturmak için Yeni düğmesine tıklayın.
+ </string>
+ <string name="NoClassifiedsText">
+ Herhangi bir İlan oluşturmadınız. Bir İlan oluşturmak için Yeni düğmesine tıklayın.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
Kullanıcının herhangi bir seçmesi veya ilanı yok
</string>
+ <string name="NoAvatarPicksText">
+ Kullanıcının favorisi yok
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Kullanıcının ilanı yok
+ </string>
<string name="PicksClassifiedsLoadingText">
Yükleniyor...
</string>
@@ -4556,6 +4583,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="share_alert">
Envanterinizden buraya öğeler sürükleyin
</string>
+ <string name="facebook_post_success">
+ Facebook&apos;ta yayınladınız.
+ </string>
<string name="flickr_post_success">
Flickr&apos;da yayınladınız.
</string>
diff --git a/indra/newview/skins/default/xui/zh/floater_picks.xml b/indra/newview/skins/default/xui/zh/floater_picks.xml
deleted file mode 100644
index a8bfcd99e3..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="精選地點"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
index 2b6eac48b3..9213cc212d 100644
--- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
覆製到收納區
</floater.string>
- <text name="desc txt">
- 描述:
- </text>
- <text name="dimensions">
- [WIDTH]像素 x [HEIGHT]像素
- </text>
- <text name="aspect_ratio">
- 預覽長寬比
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽">
- <combo_item name="Unconstrained">
- 不受限
- </combo_item>
- <combo_item name="1:1" tool_tip="群組徽章或現實世界小檔案">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] 檔案">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="個人廣告和搜索刊登廣告、地標">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="土地資料">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="個人檔案精選">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="確定" name="Keep"/>
- <button label="丟棄" name="Discard"/>
- <button label="另存為" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ 描述:
+ </text>
+ <text name="dimensions">
+ [WIDTH]像素 x [HEIGHT]像素
+ </text>
+ <text name="aspect_ratio">
+ 預覽長寬比
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="確定" name="Keep"/>
+ <button label="丟棄" name="Discard"/>
+ <button label="另存為" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_profile.xml b/indra/newview/skins/default/xui/zh/floater_profile.xml
new file mode 100644
index 0000000000..0f73f527a9
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="簡覽">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="第二人生" name="panel_profile_secondlife"/>
+ <panel label="網頁" name="panel_profile_web"/>
+ <panel label="興趣" name="panel_profile_interests"/>
+ <panel label="精選地點" name="panel_profile_picks"/>
+ <panel label="分類廣告" name="panel_profile_classifieds"/>
+ <panel label="真實世界" name="panel_profile_firstlife"/>
+ <panel label="筆記" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="確定" name="ok_btn" tool_tip="儲存變更到個人檔案後關閉"/>
+ <button label="取消" label_selected="取消" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
index 4090248083..6e1a156762 100644
--- a/indra/newview/skins/default/xui/zh/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
正在發送電郵
</string>
+ <string name="facebook_progress_str">
+ 發佈到臉書
+ </string>
<string name="profile_progress_str">
發佈
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
正在存到電腦
</string>
+ <string name="facebook_succeeded_str">
+ 圖像已上傳
+ </string>
<string name="profile_succeeded_str">
圖像已上傳
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
成功存入電腦!
</string>
+ <string name="facebook_failed_str">
+ 上傳圖像到你的臉書時間線時失敗。
+ </string>
<string name="profile_failed_str">
上傳圖像到你的檔案訊息發佈時出錯。
</string>
diff --git a/indra/newview/skins/default/xui/zh/menu_name_field.xml b/indra/newview/skins/default/xui/zh/menu_name_field.xml
new file mode 100644
index 0000000000..5eaf3461cd
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="複製顯示名稱" name="copy_display"/>
+ <menu_item_call label="複製代理名稱" name="copy_name"/>
+ <menu_item_call label="複製代理ID" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index cfde824349..4d0f1cb85b 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -2666,6 +2666,9 @@ SHA1 指紋:[MD5_DIGEST]
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
index b06ece02ad..4d3248db46 100644
--- a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="取消" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..fec4bb572a
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="未知"/>
+ <button name="info_btn" tool_tip="詳情"/>
+ <button name="profile_btn" tool_tip="察看檔案"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml
deleted file mode 100644
index aad1348e46..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="我的個人檔案" name="panel_me">
- <panel label="我的精選地點" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml
index b0e60218cf..b95dd96026 100644
--- a/indra/newview/skins/default/xui/zh/panel_people.xml
+++ b/indra/newview/skins/default/xui/zh/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="上線"/>
<accordion_tab name="tab_all" title="全部"/>
+ <accordion_tab name="tab_suggested_friends" title="你可能想要加為好友的人"/>
</accordion>
</panel>
<panel label="群組" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classified.xml b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml
new file mode 100644
index 0000000000..4eee4e8855
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ 適度成人
+ </panel.string>
+ <panel.string name="type_pg">
+ 一般普級內容
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] 瞬間傳送,[MAP] 地圖,[PROFILE] 檔案
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ 已啟用
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ 已停用
+ </panel.string>
+ <panel.string name="location_notice">
+ (儲存後將會更新)
+ </panel.string>
+ <string name="publish_label">
+ 發布
+ </string>
+ <string name="save_label">
+ 儲存
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="點按以選擇圖像"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="位置:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="內容類型:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="分類:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="建立日期:"/>
+ <text_editor name="creation_date" tool_tip="建立日期" value="[date]"/>
+ <text name="price_for_listing_label" value="刊登費:"/>
+ <text_editor name="price_for_listing" tool_tip="刊登費。">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="點按狀況:"/>
+ <text_editor name="click_through_text" tool_tip="點按資料" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="自動續訂:"/>
+ <text name="auto_renew" value="已啟用"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="描述:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ 標題:
+ </text>
+ <text name="description_label">
+ 描述:
+ </text>
+ <text name="location_label">
+ 位置:
+ </text>
+ <text name="classified_location_edit">
+ 載入中...
+ </text>
+ <button label="設定為目前位置" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="分類:"/>
+ <text name="content_type_label" value="內容類型:"/>
+ <icons_combo_box label="一般普級內容" name="content_type_edit">
+ <icons_combo_box.item label="適度成人內容" name="mature_ci" value="適度成人"/>
+ <icons_combo_box.item label="一般普級內容" name="pg_ci" value="一般普級"/>
+ </icons_combo_box>
+ <check_box label="每星期自動續訂" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="刊登費:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="刊登費。" value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="瞬間傳送" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="地圖" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="編輯" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="取消" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..89b5cdf641
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="分類廣告" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="禁止個人廣告"/>
+ <button label="新增…" name="new_btn"/>
+ <button label="刪除…" name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ 載入中…
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..9370661d7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="簡覽" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_interests.xml b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml
new file mode 100644
index 0000000000..150f3cca4f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="興趣" name="panel_profile_interests">
+ <text name="I Want To:">
+ 我想要:
+ </text>
+ <check_box label="建造" name="chk0"/>
+ <check_box label="探索" name="chk1"/>
+ <check_box label="見面" name="chk2"/>
+ <check_box label="受雇" name="chk6"/>
+ <check_box label="群組" name="chk3"/>
+ <check_box label="購買" name="chk4"/>
+ <check_box label="出售" name="chk5"/>
+ <check_box label="招人" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (載入中...)
+ </line_editor>
+ <text name="Skills:">
+ 技能:
+ </text>
+ <check_box label="材質" name="schk0"/>
+ <check_box label="架構" name="schk1"/>
+ <check_box label="建模" name="schk3"/>
+ <check_box label="計畫活動" name="schk2"/>
+ <check_box label="建腳本" name="schk4"/>
+ <check_box label="定製角色" name="schk5"/>
+ <line_editor name="skills_edit">
+ (載入中...)
+ </line_editor>
+ <text name="Languages:">
+ 語言:
+ </text>
+ <line_editor name="languages_edit">
+ (載入中...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_notes.xml b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml
new file mode 100644
index 0000000000..17e1a997da
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="筆記和隱私" name="panel_notes">
+ <text name="status_message" value="關於這化身的私人筆記:"/>
+ <text name="status_message2" value="允許這個化身:"/>
+ <check_box label="看見我何時上線" name="status_check"/>
+ <check_box label="在世界地圖上找到我" name="map_check"/>
+ <check_box label="邊輯,刪除或取下我的物件" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_pick.xml b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml
new file mode 100644
index 0000000000..5f8d6a2ba5
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (儲存後將會更新)
+ </panel.string>
+ <line_editor name="pick_location">
+ 載入中…
+ </line_editor>
+ <button label="瞬間傳送" name="teleport_btn"/>
+ <button label="顯示在地圖上" name="show_on_map_btn"/>
+ <button label="設定位置" name="set_to_curr_location_btn" tool_tip="設定為目前位置"/>
+ <button label="儲存精選地點" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_picks.xml b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml
new file mode 100644
index 0000000000..8f189d1308
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="精選地點" name="panel_picks">
+ <string name="no_picks" value="無精選地點"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ 告訴大家你在Second Life中最愛的去處。
+ </text>
+ <button label="新增…" name="new_btn"/>
+ <button label="刪除…" name="delete_btn"/>
+ <text name="picks_panel_text">
+ 載入中…
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..da4aafce55
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="簡覽" name="panel_profile">
+ <string name="status_online">
+ 目前在線
+ </string>
+ <string name="status_offline">
+ 目前離線
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="無"/>
+ <string name="no_group_text" value="無"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="開發者"/>
+ <string name="FSSupp" value="支援"/>
+ <string name="FSQualityAssurance" value="除錯獵人"/>
+ <string name="FSGW" value="網關"/>
+ <text name="name_label" value="名稱:"/>
+ <button label="名稱:" name="set_name" tool_tip="設定顯示名稱"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(載入中...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="狀態不明"/>
+ <text name="label" value="Second Life生日:"/>
+ <text name="label2" value="帳戶:"/>
+ <text name="partner_label" value="伴侶:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="群組:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="邀請加入群組"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="關於:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="贈與物品:"/>
+ <text name="Give inventory" tool_tip="把收納區物品放到這裡,送給此人。">
+ 把收納區物品放到這裡。
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="在地圖上查找" label_selected="在地圖上查找" name="show_on_map_btn" tool_tip="在地圖上找出這個居民"/>
+ <button label="支付" label_selected="支付" name="pay" tool_tip="付款給這個居民"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="發出瞬間傳送邀請" label_selected="發出瞬間傳送邀請" name="teleport" tool_tip="向這個居民發出瞬間傳送邀請"/>
+ <button label="即時訊息" label_selected="即時訊息" name="im" tool_tip="開啟即時訊息會話"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="加為朋友" label_selected="加為朋友" name="add_friend" tool_tip="向這個居民發出交友邀請"/>
+ <button label="封鎖" name="block" tool_tip="封鎖這位居民"/>
+ <button label="解除封鎖" name="unblock" tool_tip="不再封鎖這位居民"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="在搜尋結果中顯示" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_web.xml b/indra/newview/skins/default/xui/zh/panel_profile_web.xml
new file mode 100644
index 0000000000..566651dceb
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="網頁" name="panel_profile_web">
+ <panel.string name="LoadTime" value="載入時間:[TIME]秒"/>
+ <line_editor name="url_edit">
+ (載入中…)
+ </line_editor>
+ <flyout_button label="載入" name="load" tool_tip="用內嵌瀏覽器載入此個人檔案頁面。">
+ <flyout_button.item label="開啓内部瀏覽器" name="open_item"/>
+ <flyout_button.item label="開啓外部瀏覽器" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="彈出式個人檔案網頁"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
index 85e759e445..81bce46876 100644
--- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="地形提升限制" name="terrain_raise_spin"/>
<spinner label="地形降低限制" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形材質(須 512x512,24 位元 .tga 檔格式)
+ 地形材質(須 1024x1024,24 位元 .tga 檔格式)
</text>
<text name="height_text_lbl">
1(低)
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index 3221cde3b7..bdb16c9bf1 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -187,7 +187,7 @@ LibVLC版本:[LIBVLC_VERSION]N]
<string name="LoginFailedNoNetwork">
網路錯誤:無法建立連線,請檢查網路連線是否正常。
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
登入失敗。
</string>
<string name="Quit">
@@ -353,6 +353,24 @@ http://secondlife.com/viewer-access-faq
<string name="TestingDisconnect">
測試瀏覽器斷線
</string>
+ <string name="SocialFacebookConnecting">
+ 連通臉書中…
+ </string>
+ <string name="SocialFacebookPosting">
+ 發佈中…
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ 臉書連通中斷中…
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ 連通臉書時出問題
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ 發佈到臉書時出問題
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ 試圖中斷臉書連通時出問題
+ </string>
<string name="SocialFlickrConnecting">
連通 Flickr 中…
</string>
@@ -667,9 +685,6 @@ http://secondlife.com/viewer-access-faq
<string name="GroupNameNone">
(無)
</string>
- <string name="AvalineCaller">
- Avaline 通話者 [ORDER]
- </string>
<string name="AssetErrorNone">
無錯誤
</string>
@@ -2569,9 +2584,21 @@ http://secondlife.com/support 求助解決問題。
<string name="NoPicksClassifiedsText">
你尚未建立任何精選地點或個人廣告。 點按下面的 + 按鈕建立精選地點或個人廣告。
</string>
+ <string name="NoPicksText">
+ 你尚未建立任何精選地點。 點按「新增」按鈕建立精選地點。
+ </string>
+ <string name="NoClassifiedsText">
+ 你尚未建立任何分類廣告。 點按「新增」按鈕建立分類廣告。
+ </string>
<string name="NoAvatarPicksClassifiedsText">
使用者無精選地點或個人廣告
</string>
+ <string name="NoAvatarPicksText">
+ 使用者沒有精選地點
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ 使用者沒有分類廣告
+ </string>
<string name="PicksClassifiedsLoadingText">
載入中...
</string>
@@ -4549,6 +4576,9 @@ http://secondlife.com/support 求助解決問題。
<string name="share_alert">
將收納區物品拖曳到這裡
</string>
+ <string name="facebook_post_success">
+ 成功發佈到臉書。
+ </string>
<string name="flickr_post_success">
成功發佈到 Flickr。
</string>
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index a52c3dcef9..696fe3536c 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -223,6 +223,7 @@ bool llHashedUniqueID(unsigned char* id)
#include "../llappviewer.h"
void LLAppViewer::forceQuit(void) {}
bool LLAppViewer::isUpdaterMissing() { return true; }
+bool LLAppViewer::waitForUpdater() { return false; }
LLAppViewer * LLAppViewer::sInstance = 0;
//-----------------------------------------------------------------------------
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index de5ac5ed3d..59eb18b734 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -568,6 +568,7 @@ class WindowsManifest(ViewerManifest):
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
@@ -954,6 +955,7 @@ class DarwinManifest(ViewerManifest):
self.path("licenses-mac.txt", dst="licenses.txt")
self.path("featuretable_mac.txt")
+ self.path("cube.dae")
self.path("SecondLife.nib")
with self.prefix(src=pkgdir,dst=""):
@@ -1427,6 +1429,7 @@ class LinuxManifest(ViewerManifest):
print("Skipping llcommon.so (assuming llcommon was linked statically)")
self.path("featuretable_linux.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index 8a7e6407ed..5d50d1e182 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -257,21 +257,25 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
if (printable_params["wait_for_updater"].asBoolean())
{
std::string reason_response = responses["data"]["reason"].asString();
- if (reason_response == "update") // No point waiting if not an update
+ // Timeout should produce the isUndefined() object passed here.
+ if (reason_response == "update")
{
- // Timeout should produce the isUndefined() object passed here.
LL_INFOS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD());
-
- if (updater.isUndefined())
- {
- LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
- << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
- }
+ }
+ else
+ {
+ LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
+ updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 3, LLSD());
+ }
+ if (updater.isUndefined())
+ {
+ LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
}
}
diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py
index e7b86a88fa..4a0773951e 100644
--- a/scripts/content_tools/anim_tool.py
+++ b/scripts/content_tools/anim_tool.py
@@ -611,6 +611,7 @@ def main(*argv):
parser = argparse.ArgumentParser(description="process SL animations")
parser.add_argument("--verbose", help="verbose flag", action="store_true")
parser.add_argument("--dump", help="dump to stdout", action="store_true")
+ parser.add_argument("--use_aliases", help="use alias names for bones", action="store_true")
parser.add_argument("--rot", help="specify sequence of rotations", type=float_triple, nargs="+")
parser.add_argument("--rand_pos", help="request NUM random positions (default %(default)s)",
metavar="NUM", type=int, default=2)
@@ -637,6 +638,7 @@ def main(*argv):
parser.add_argument("--no_hud", help="omit hud joints from list of attachments", action="store_true")
parser.add_argument("--base_priority", help="set base priority", type=int)
parser.add_argument("--joint_priority", help="set joint priority for all joints", type=int)
+ parser.add_argument("--force_joints", help="don't check validity of joint names", action="store_true")
parser.add_argument("infilename", help="name of a .anim file to input")
parser.add_argument("outfilename", nargs="?", help="name of a .anim file to output")
args = parser.parse_args(argv)
@@ -661,7 +663,12 @@ def main(*argv):
if lad_tree is None:
raise Error("failed to parse " + args.lad)
if args.joints:
- joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud)
+ if args.force_joints:
+ joints = args.joints
+ else:
+ joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud)
+ if args.use_aliases:
+ joints = map(lambda name: "avatar_" + name, joints)
if args.verbose:
print("joints resolved to",joints)
for name in joints:
diff --git a/scripts/content_tools/skel_tool.py b/scripts/content_tools/skel_tool.py
index 449ecd6a6c..696e4e2923 100644
--- a/scripts/content_tools/skel_tool.py
+++ b/scripts/content_tools/skel_tool.py
@@ -72,6 +72,22 @@ def check_symmetry(name, field, vec1, vec2):
if vec1[2] != vec2[2]:
print(name,field,"z match fail")
+def enforce_alias_rules(tree, element, fix=False):
+ if element.tag != "bone":
+ return
+ alias_lis = []
+ aliases = element.get("aliases")
+ if aliases:
+ alias_lis = aliases.split(" ")
+ name = element.get("name")
+ if name:
+ std_alias = "avatar_" + name
+ if not std_alias in alias_lis:
+ print "missing expected alias",name,std_alias
+ for alias in alias_lis:
+ if alias.startswith("avatar_") and alias != std_alias:
+ print "invalid avatar_ alias",name,alias
+
def enforce_symmetry(tree, element, field, fix=False):
name = element.get("name")
if not name:
@@ -209,6 +225,7 @@ def validate_skel_tree(tree, ogtree, reftree, fix=False):
unfixable += 1
fix_name(element)
+ enforce_alias_rules(tree, element, fix)
enforce_precision_rules(element)
for field in ["pos","pivot"]:
enforce_symmetry(tree, element, field, fix)