summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNyx Linden <nyx@lindenlab.com>2013-08-16 19:31:16 -0400
committerNyx Linden <nyx@lindenlab.com>2013-08-16 19:31:16 -0400
commit5ae117aff6bfbc3c07876146ca270129dd91a047 (patch)
tree462f491cc055aa296b9da0041a322cd9512c045b
parent8abd6ed6b8c294ec6bfca59929dbcc71cd65c3a3 (diff)
parent32b8d398eca5eaa4ca99aa48839ad64d97954cae (diff)
merge with viewer-release
-rwxr-xr-x.hgtags64
-rwxr-xr-xBuildParams11
-rw-r--r--NORSPEC-207.patch164
-rwxr-xr-xdoc/contributions.txt5
-rwxr-xr-xindra/cmake/APR.cmake2
-rwxr-xr-xindra/cmake/BuildVersion.cmake2
-rwxr-xr-xindra/cmake/CMakeLists.txt1
-rwxr-xr-xindra/cmake/Copy3rdPartyLibs.cmake3
-rwxr-xr-xindra/cmake/DragDrop.cmake24
-rwxr-xr-xindra/cmake/Havok.cmake72
-rwxr-xr-xindra/cmake/LLPrimitive.cmake7
-rwxr-xr-xindra/cmake/LLRender.cmake4
-rwxr-xr-xindra/cmake/LLWindow.cmake10
-rwxr-xr-xindra/cmake/VisualLeakDetector.cmake12
-rwxr-xr-xindra/lib/python/indra/util/llversion.py107
-rwxr-xr-xindra/linux_crash_logger/CMakeLists.txt4
-rw-r--r--indra/llappearance/llpolymorph.cpp16
-rw-r--r--indra/llaudio/llaudioengine_fmodex.cpp30
-rwxr-xr-xindra/llaudio/llwindgen.h8
-rwxr-xr-xindra/llcommon/llapp.cpp4
-rwxr-xr-xindra/llcommon/llapr.cpp4
-rwxr-xr-xindra/llcommon/llavatarname.h2
-rwxr-xr-xindra/llcommon/llcoros.cpp4
-rwxr-xr-xindra/llcommon/llerror.cpp27
-rwxr-xr-xindra/llcommon/llerror.h13
-rwxr-xr-xindra/llcommon/llfasttimer.cpp2
-rwxr-xr-xindra/llcommon/llfile.cpp24
-rwxr-xr-xindra/llcommon/llfile.h4
-rwxr-xr-xindra/llcommon/llsdserialize_xml.cpp4
-rwxr-xr-xindra/llcommon/tests/llprocess_test.cpp5
-rwxr-xr-xindra/llmath/llvector4a.h6
-rwxr-xr-xindra/llmath/llvolume.cpp422
-rwxr-xr-xindra/llmath/llvolume.h36
-rwxr-xr-xindra/llmath/llvolumeoctree.cpp66
-rwxr-xr-xindra/llmath/llvolumeoctree.h8
-rwxr-xr-xindra/llmessage/CMakeLists.txt2
-rwxr-xr-xindra/llmessage/llares.cpp29
-rwxr-xr-xindra/llmessage/llareslistener.cpp9
-rwxr-xr-xindra/llmessage/llurlrequest.cpp10
-rwxr-xr-xindra/llmessage/tests/llhttpclient_test.cpp2
-rwxr-xr-xindra/llplugin/slplugin/slplugin-objc.mm2
-rwxr-xr-xindra/llprimitive/CMakeLists.txt4
-rw-r--r--indra/llprimitive/llmaterial.cpp227
-rw-r--r--indra/llprimitive/llmaterial.h155
-rw-r--r--indra/llprimitive/llmaterialid.cpp183
-rw-r--r--indra/llprimitive/llmaterialid.h76
-rwxr-xr-xindra/llprimitive/llprimitive.cpp89
-rwxr-xr-xindra/llprimitive/llprimitive.h8
-rwxr-xr-xindra/llprimitive/llprimtexturelist.cpp19
-rwxr-xr-xindra/llprimitive/llprimtexturelist.h4
-rwxr-xr-xindra/llprimitive/lltextureentry.cpp42
-rwxr-xr-xindra/llprimitive/lltextureentry.h22
-rwxr-xr-xindra/llrender/CMakeLists.txt2
-rwxr-xr-xindra/llrender/llgl.cpp42
-rwxr-xr-xindra/llrender/llgl.h8
-rwxr-xr-xindra/llrender/llglheaders.h16
-rwxr-xr-xindra/llrender/llglslshader.cpp370
-rwxr-xr-xindra/llrender/llglslshader.h48
-rw-r--r--indra/llrender/llimagegl.cpp50
-rwxr-xr-xindra/llrender/llrender.h8
-rwxr-xr-xindra/llrender/llrendertarget.cpp32
-rwxr-xr-xindra/llrender/llrendertarget.h6
-rwxr-xr-xindra/llrender/llshadermgr.cpp44
-rwxr-xr-xindra/llrender/llshadermgr.h10
-rwxr-xr-xindra/llrender/llvertexbuffer.cpp91
-rwxr-xr-xindra/llrender/llvertexbuffer.h8
-rwxr-xr-xindra/llui/lllocalcliprect.cpp10
-rwxr-xr-xindra/llui/llxuiparser.cpp22
-rwxr-xr-xindra/llvfs/lldir_mac.cpp2
-rwxr-xr-xindra/llvfs/lldir_win32.cpp2
-rwxr-xr-xindra/llvfs/llvfile.cpp2
-rwxr-xr-xindra/llvfs/llvfs_objc.mm2
-rwxr-xr-xindra/llwindow/CMakeLists.txt14
-rwxr-xr-xindra/llxml/CMakeLists.txt2
-rwxr-xr-xindra/lscript/lscript_compile/indra.l8
-rwxr-xr-xindra/lscript/lscript_compile/indra.y7
-rwxr-xr-xindra/mac_crash_logger/CrashReporter.nibbin32288 -> 32286 bytes
-rwxr-xr-xindra/media_plugins/winmmshim/winmm_shim.cpp2
-rwxr-xr-xindra/newview/CMakeLists.txt44
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rwxr-xr-xindra/newview/app_settings/settings.xml85
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/alphaF.glsl210
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl65
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl20
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/alphaV.glsl138
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl5
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/avatarF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl4
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl6
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl67
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/bumpF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl6
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/bumpV.glsl6
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl15
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl72
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl67
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl696
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl144
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl74
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl101
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl69
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl46
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl6
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl10
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl10
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/shadowF.glsl5
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/shadowV.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/skyF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl112
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl128
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl36
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/terrainF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/treeF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/waterF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/environment/waterV.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl69
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl59
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl42
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl4
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl4
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl6
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl6
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl8
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl4
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl4
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl4
-rwxr-xr-xindra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl6
-rwxr-xr-xindra/newview/app_settings/shaders/class1/transform/binormalV.glsl6
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/alphaF.glsl164
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl63
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl62
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl5
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/alphaV.glsl128
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl122
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl139
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl108
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl46
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl46
-rwxr-xr-xindra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl2
-rwxr-xr-xindra/newview/character/avatar_lad.xml5
-rwxr-xr-xindra/newview/gpu_table.txt516
-rwxr-xr-xindra/newview/llagent.cpp4
-rwxr-xr-xindra/newview/llagentcamera.cpp32
-rwxr-xr-xindra/newview/llappviewer.cpp374
-rwxr-xr-xindra/newview/llappviewer.h5
-rwxr-xr-xindra/newview/llappviewerlinux.cpp4
-rwxr-xr-xindra/newview/llappviewerlinux.h2
-rwxr-xr-xindra/newview/llappviewerwin32.cpp6
-rwxr-xr-xindra/newview/llappviewerwin32.h2
-rwxr-xr-xindra/newview/lldrawable.cpp43
-rwxr-xr-xindra/newview/lldrawable.h2
-rwxr-xr-xindra/newview/lldrawpool.cpp32
-rwxr-xr-xindra/newview/lldrawpool.h20
-rwxr-xr-xindra/newview/lldrawpoolalpha.cpp164
-rwxr-xr-xindra/newview/lldrawpoolalpha.h7
-rwxr-xr-xindra/newview/lldrawpoolavatar.cpp288
-rwxr-xr-xindra/newview/lldrawpoolavatar.h71
-rwxr-xr-xindra/newview/lldrawpoolbump.cpp20
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp217
-rw-r--r--indra/newview/lldrawpoolmaterials.h75
-rwxr-xr-xindra/newview/lldrawpoolsimple.cpp232
-rwxr-xr-xindra/newview/lldrawpoolsimple.h53
-rwxr-xr-xindra/newview/llface.cpp751
-rwxr-xr-xindra/newview/llface.h37
-rwxr-xr-xindra/newview/llfloaterimcontainer.cpp2
-rwxr-xr-xindra/newview/llfloaterimnearbychat.cpp2
-rwxr-xr-xindra/newview/llfloaterpreference.cpp11
-rwxr-xr-xindra/newview/llfriendcard.cpp2
-rwxr-xr-xindra/newview/llgesturemgr.cpp2
-rwxr-xr-xindra/newview/llhudicon.cpp21
-rwxr-xr-xindra/newview/llhudicon.h4
-rwxr-xr-xindra/newview/llhudnametag.cpp18
-rwxr-xr-xindra/newview/llhudnametag.h2
-rwxr-xr-xindra/newview/llinventorybridge.cpp2
-rwxr-xr-xindra/newview/lllocalbitmaps.cpp65
-rwxr-xr-xindra/newview/lllocalbitmaps.h4
-rwxr-xr-xindra/newview/lllogininstance.cpp31
-rw-r--r--indra/newview/llmaterialmgr.cpp782
-rw-r--r--indra/newview/llmaterialmgr.h130
-rwxr-xr-xindra/newview/llmeshrepository.cpp1
-rwxr-xr-xindra/newview/llpaneleditwearable.h4
-rwxr-xr-xindra/newview/llpanelface.cpp1889
-rwxr-xr-xindra/newview/llpanelface.h393
-rwxr-xr-xindra/newview/llphysicsmotion.cpp12
-rwxr-xr-xindra/newview/llselectmgr.cpp185
-rwxr-xr-xindra/newview/llselectmgr.h20
-rwxr-xr-xindra/newview/llsidepanelappearance.cpp2
-rwxr-xr-xindra/newview/llsidepanelappearance.h2
-rwxr-xr-xindra/newview/llspatialpartition.cpp278
-rwxr-xr-xindra/newview/llspatialpartition.h27
-rwxr-xr-xindra/newview/llstartup.cpp2
-rwxr-xr-xindra/newview/lltextureatlas.cpp2
-rwxr-xr-xindra/newview/lltexturecache.cpp14
-rwxr-xr-xindra/newview/lltexturecache.h2
-rwxr-xr-xindra/newview/lltexturectrl.cpp25
-rwxr-xr-xindra/newview/lltexturectrl.h8
-rwxr-xr-xindra/newview/llvieweraudio.cpp26
-rwxr-xr-xindra/newview/llviewercontrol.cpp21
-rwxr-xr-xindra/newview/llviewerdisplay.cpp37
-rwxr-xr-xindra/newview/llviewerinventory.h6
-rwxr-xr-xindra/newview/llviewermenu.cpp82
-rwxr-xr-xindra/newview/llviewerobject.cpp249
-rwxr-xr-xindra/newview/llviewerobject.h32
-rwxr-xr-xindra/newview/llviewerregion.h2
-rwxr-xr-xindra/newview/llviewershadermgr.cpp291
-rwxr-xr-xindra/newview/llviewershadermgr.h16
-rwxr-xr-xindra/newview/llviewerstatsrecorder.cpp6
-rwxr-xr-xindra/newview/llviewertexture.cpp417
-rwxr-xr-xindra/newview/llviewertexturelist.cpp13
-rwxr-xr-xindra/newview/llviewerwindow.cpp134
-rwxr-xr-xindra/newview/llviewerwindow.h23
-rwxr-xr-xindra/newview/llvoavatar.cpp37
-rwxr-xr-xindra/newview/llvoavatar.h24
-rwxr-xr-xindra/newview/llvograss.cpp28
-rwxr-xr-xindra/newview/llvograss.h8
-rwxr-xr-xindra/newview/llvoiceclient.cpp7
-rwxr-xr-xindra/newview/llvoiceclient.h1
-rwxr-xr-xindra/newview/llvoicevivox.cpp800
-rwxr-xr-xindra/newview/llvoicevivox.h27
-rwxr-xr-xindra/newview/llvopartgroup.cpp5
-rwxr-xr-xindra/newview/llvosurfacepatch.cpp20
-rwxr-xr-xindra/newview/llvosurfacepatch.h8
-rwxr-xr-xindra/newview/llvotree.cpp139
-rwxr-xr-xindra/newview/llvotree.h13
-rwxr-xr-xindra/newview/llvovolume.cpp672
-rwxr-xr-xindra/newview/llvovolume.h17
-rwxr-xr-xindra/newview/llwlparamset.cpp8
-rwxr-xr-xindra/newview/llworld.cpp22
-rwxr-xr-xindra/newview/llworld.h6
-rwxr-xr-xindra/newview/pipeline.cpp726
-rwxr-xr-xindra/newview/pipeline.h68
-rwxr-xr-xindra/newview/skins/default/colors.xml9
-rw-r--r--indra/newview/skins/default/textures/flatnormal.tgabin0 -> 92 bytes
-rw-r--r--indra/newview/skins/default/textures/materials_ui_x_24.pngbin0 -> 602 bytes
-rwxr-xr-xindra/newview/skins/default/textures/textures.xml1
-rwxr-xr-xindra/newview/skins/default/xui/da/menu_viewer.xml2
-rwxr-xr-xindra/newview/skins/default/xui/de/menu_viewer.xml9
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_tools.xml526
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_viewer.xml27
-rwxr-xr-xindra/newview/skins/default/xui/en/notifications.xml10
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_preferences_graphics1.xml25
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml766
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml4
-rwxr-xr-xindra/newview/skins/default/xui/es/menu_viewer.xml2
-rwxr-xr-xindra/newview/skins/default/xui/fr/menu_viewer.xml2
-rwxr-xr-xindra/newview/skins/default/xui/it/menu_viewer.xml2
-rwxr-xr-xindra/newview/skins/default/xui/ja/menu_viewer.xml2
-rwxr-xr-xindra/newview/skins/default/xui/pl/menu_viewer.xml2
-rwxr-xr-xindra/newview/skins/default/xui/pt/menu_viewer.xml2
-rwxr-xr-xindra/newview/skins/default/xui/ru/menu_viewer.xml18
-rwxr-xr-xindra/newview/skins/default/xui/tr/menu_viewer.xml2
-rwxr-xr-xindra/newview/skins/default/xui/zh/menu_viewer.xml2
-rwxr-xr-xindra/newview/tests/llmediadataclient_test.cpp1
-rwxr-xr-xindra/newview/viewer_manifest.py15
-rwxr-xr-xindra/test/llsaleinfo_tut.cpp2
-rwxr-xr-xindra/viewer_components/login/lllogin.cpp36
277 files changed, 13824 insertions, 5002 deletions
diff --git a/.hgtags b/.hgtags
index 08ec2de7fc..9ca419211e 100755
--- a/.hgtags
+++ b/.hgtags
@@ -72,35 +72,35 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip
9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
+42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
+42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
+c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
+c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
-42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
-42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
-c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
-c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
+214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
+214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py
ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start
d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1
d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2
0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2
+8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
+8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
-214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
-214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1
7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start
bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
-5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
+5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
@@ -119,50 +119,50 @@ e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start
9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
-6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
+6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1
be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1
+057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
+057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start
09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1
09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1
+6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
+6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1
-057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
-057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
-6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
-6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
+493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
+493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1
2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
-54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
-ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix
4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix
+54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
+ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1
599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1
+fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
+fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start
b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
-fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
-fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
+1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
+1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start
364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1
364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start
42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1
42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
-1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
-1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2
e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
@@ -170,9 +170,9 @@ b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1
61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2
61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2
-586907287be581817b2422b5137971b22d54ea48 3.0.4-start
0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release
0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
+586907287be581817b2422b5137971b22d54ea48 3.0.4-start
92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start
c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start
2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1
@@ -193,11 +193,11 @@ e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
+a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
+a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
-a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
-a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
@@ -279,6 +279,10 @@ a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3
9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184
ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release
+6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
+7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
+8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
+351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182
@@ -294,13 +298,9 @@ ae5c83dd61d2d37c45f1d5b8bf2b036d87599f1b DRTVWR-198
b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2
37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200
182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3
-6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
-7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201
84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4
573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5
-8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
-351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212
015012c2b740ccdec8a8c3d6e5f898449ecfe0b8 DRTVWR-213
62b07aa81b1957897c3846292bb9412977b0af6c 3.3.4-beta6
@@ -457,3 +457,9 @@ a314f1c94374ab1f6633dd2983f7090a68663eb2 3.5.2-beta4
9013c07bfe1c51107233f1924dccdcc5057dd909 3.5.2-beta6
9b1b6f33aa5394b27bb652b31b5cb81ef6060370 3.5.2-release
a277b841729f2a62ba1e34acacc964bc13c1ad6f 3.5.3-release
+fb1630153bac5552046ea914af3f14deabc1def8 3.6.0-materials-beta1
+69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
+69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
+0a56f33ad6aa112032b14a41dad759ad377bdde9 3.6.0-release
+75cf8e855ae1af6895a35da475314c2b5acf1850 3.6.1-release
+f6741d5fe8d632651424484df0fe0cb4a01e9fbe 3.6.2-release
diff --git a/BuildParams b/BuildParams
index a4b361261f..84d30f651b 100755
--- a/BuildParams
+++ b/BuildParams
@@ -60,6 +60,7 @@ viewer-release.build_debug_release_separately = true
viewer-release.build_viewer_update_version_manager = true
viewer-release.codeticket_add_context = false
+
# ========================================
# mesh-development
# ========================================
@@ -122,6 +123,14 @@ viewer-pathfinding.build_CYGWIN_Debug = false
viewer-pathfinding.build_viewer_update_version_manager = false
# ========================================
+# viewer-materials
+# ========================================
+
+viewer-materials.viewer_channel = "Second Life Beta Materials"
+viewer-materials.build_debug_release_separately = true
+viewer-materials.build_CYGWIN_Debug = false
+viewer-materials.build_viewer_update_version_manager = false
+
# viewer-chui
#
# ========================================
@@ -189,3 +198,5 @@ runway.build_viewer_update_version_manager = false
# eof
+
+
diff --git a/NORSPEC-207.patch b/NORSPEC-207.patch
new file mode 100644
index 0000000000..a1c1447bda
--- /dev/null
+++ b/NORSPEC-207.patch
@@ -0,0 +1,164 @@
+diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.cpp
+--- a/indra/llprimitive/llrendermaterialtable.cpp Wed May 15 17:57:21 2013 +0000
++++ b/indra/llprimitive/llrendermaterialtable.cpp Wed May 22 14:23:04 2013 -0700
+@@ -184,6 +184,44 @@
+ }
+ }
+
++// 'v' is an integer value for 100ths of radians (don't ask...)
++//
++void LLRenderMaterialEntry::LLRenderMaterial::setSpecularMapRotation(S32 v) const
++{
++ // Store the fact that we're using the new rotation rep
++ //
++ m_flags |= kNewSpecularMapRotation;
++
++ // Store 'sign bit' in our m_flags
++ //
++ m_flags &= ~kSpecularMapRotationNegative;
++ m_flags |= (specularMapRotation < 0) ? kSpecularMapRotationNegative : 0;
++
++ specularRotation = abs(specularRotation);
++ specularRotation = llmin(specularRotation, MAX_MATERIAL_MAP_ROTATION);
++
++ m_specularRotation = (U16)(abs(specularMapRotation));
++}
++
++// 'v' is an integer value for 100ths of radians (don't ask...)
++//
++void LLRenderMaterialEntry::LLRenderMaterial::setNormalMapRotation(S32 v) const
++{
++
++ // Store the fact that we're using the new rep for this material
++ //
++ m_flags |= kNewNormalMapRotation;
++
++ // Store 'sign bit' in our m_flags
++ //
++ m_flags &= ~kNormalMapRotationNegative;
++ m_flags |= (normalMapRotation < 0) ? kNormalMapRotationNegative : 0;
++
++ normalRotation = abs(normalRotation);
++ normalRotation = llmin(normalRotation, MAX_MATERIAL_MAP_ROTATION);
++
++ m_normalRotation = (U16)(abs(normalMapRotation));
++}
+
+ void LLRenderMaterialEntry::LLRenderMaterial::asLLSD( LLSD& dest ) const
+ {
+@@ -193,20 +231,45 @@
+ dest["NormOffsetY"] = (S32)m_normalOffsetY;
+ dest["NormRepeatX"] = m_normalRepeatX;
+ dest["NormRepeatY"] = m_normalRepeatY;
+- dest["NormRotation"] = (S32)m_normalRotation;
++
++ S32 value = (S32)m_normalMapRotation;
++
++ // If we don't have the flag for new rotations set,
++ // then we need to convert it now
++ if (!(m_flags & kNewNormalMapRotation))
++ {
++ F32 old_radians = ((F32)m_normalMapRotation / 10000.0f)
++ S32 new_val = (S32)(old_radians * 100.0f);
++ setNormalMapRotation(new_Val);
++ }
++
++ dest["NormRotation"] = (m_flags & kNormalMapRotationNegative) ? -(S32)m_normalRotation : (S32)m_normalRotation;
+
+ dest["SpecOffsetX"] = (S32)m_specularOffsetX;
+ dest["SpecOffsetY"] = (S32)m_specularOffsetY;
+ dest["SpecRepeatX"] = m_specularRepeatX;
+ dest["SpecRepeatY"] = m_specularRepeatY;
+- dest["SpecRotation"] = (S32)m_specularRotation;
++
++
++ value = (S32)m_specularRotation;
++
++ // If we don't have the flag for new rotations set,
++ // then we need to convert it now
++ if (!(m_flags & kNewSpecularMapRotation))
++ {
++ F32 old_radians = ((F32)m_specularMapRotation / 10000.0f)
++ S32 new_val = (S32)(old_radians * 100.0f);
++ setSpecularMapRotation(new_Val);
++ }
++
++ dest["SpecRotation"] = (m_flags & kSpecularMapRotationNegative) ? -(S32)m_specularRotation : (S32)m_specularRotation;
+
+ dest["SpecMap"] = m_specularMap;
+ dest["SpecColor"] = m_specularLightColor.getValue();
+ dest["SpecExp"] = (S32)m_specularLightExponent;
+ dest["EnvIntensity"] = (S32)m_environmentIntensity;
+ dest["AlphaMaskCutoff"] = (S32)m_alphaMaskCutoff;
+- dest["DiffuseAlphaMode"] = (S32)m_diffuseAlphaMode;
++ dest["DiffuseAlphaMode"] = (S32)(m_diffuseAlphaMode & 0xF);
+
+ }
+
+@@ -217,7 +280,10 @@
+ m_normalOffsetY = (U16)materialDefinition["NormOffsetY"].asInteger();
+ m_normalRepeatX = materialDefinition["NormRepeatX"].asInteger();
+ m_normalRepeatY = materialDefinition["NormRepeatY"].asInteger();
+- m_normalRotation = (U16)materialDefinition["NormRotation"].asInteger();
++
++ S32 normalRotation = materialDefinition["NormRotation"].asInteger();
++
++ setNormalMapRotation(normalRotation);
+
+ m_specularMap = materialDefinition["SpecMap"].asUUID();
+
+@@ -225,7 +291,10 @@
+ m_specularOffsetY = (U16)materialDefinition["SpecOffsetY"].asInteger();
+ m_specularRepeatX = materialDefinition["SpecRepeatX"].asInteger();
+ m_specularRepeatY = materialDefinition["SpecRepeatY"].asInteger();
+- m_specularRotation = (U16)materialDefinition["SpecRotation"].asInteger();
++
++ S32 specularRotation = materialDefinition["SpecRotation"].asInteger();
++
++ setSpecularMapRotation(specularRotation);
+
+ m_specularLightColor.setValue( materialDefinition["SpecColor"] );
+ m_specularLightExponent = (U8)materialDefinition["SpecExp"].asInteger();
+diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.h
+--- a/indra/llprimitive/llrendermaterialtable.h Wed May 15 17:57:21 2013 +0000
++++ b/indra/llprimitive/llrendermaterialtable.h Wed May 22 14:23:04 2013 -0700
+@@ -89,11 +89,17 @@
+
+ void computeID();
+
++
+ struct LLRenderMaterial
+ {
+ void asLLSD( LLSD& dest ) const;
+ void setFromLLSD( const LLSD& materialDefinition );
+
++ void setNormalMapRotation(S32 v);
++ void setSpecularMapRotation(S32 v);
++
++ const S32 MAX_MATERIAL_MAP_ROTATION = 62800;
++
+ // 36 bytes
+ LLUUID m_normalMap;
+ LLUUID m_specularMap;
+@@ -119,7 +125,20 @@
+ U8 m_specularLightExponent;
+ U8 m_environmentIntensity;
+ U8 m_alphaMaskCutoff;
+- U8 m_diffuseAlphaMode;
++ U8 m_diffuseAlphaMode : 4;
++ U8 m_flags : 4;
++ };
++
++ // Flags stored in LLRenderMaterial::m_flags to differentiate 'old' rotation format
++ // which doesn't handle negative or large rotations correctly from new format.
++ // All ancient materials will have these flags unset as the values for diffuseAlphaMode
++ // from which the bits were stolen never used more than the bottom 2 bits.
++ //
++ enum RenderMaterialFlags {
++ kNewNormalMapRotation = 0x1,
++ kNewSpecularMapRotation = 0x2,
++ kNormalMapRotationNegative = 0x4,
++ kSpecularMapRotationNegative = 0x8
+ };
+
+ friend struct eastl::hash<LLRenderMaterial>;
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 8c5bb3d576..66ccb404a8 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -404,6 +404,7 @@ Ganymedes Costagravas
Geenz Spad
STORM-1823
STORM-1900
+ NORSPEC-229
Gene Frostbite
GeneJ Composer
Geneko Nemeth
@@ -647,6 +648,7 @@ Jonathan Yap
STORM-1872
STORM-1858
STORM-1862
+ OPEN-161
Kadah Coba
STORM-1060
STORM-1843
@@ -1023,6 +1025,7 @@ Ryozu Kojima
VWR-287
Sachi Vixen
Sahkolihaa Contepomi
+ MATBUG-102
Saii Hallard
SaintLEOlions Zimer
Salahzar Stenvaag
@@ -1173,6 +1176,7 @@ Techwolf Lupindo
SNOW-746
VWR-12385
VWR-20893
+ OPEN-161
Templar Merlin
tenebrous pau
VWR-247
@@ -1240,6 +1244,7 @@ Vadim Bigbear
VWR-2681
Vaalith Jinn
STORM-64
+ MATBUG-8
Vector Hastings
VWR-8726
Veritas Raymaker
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index 492ba2adea..a87027f5f6 100755
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -49,7 +49,7 @@ else (STANDALONE)
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} uuid)
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)
endif (LINUX)
endif (STANDALONE)
diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake
index 7fc6957254..87f078be23 100755
--- a/indra/cmake/BuildVersion.cmake
+++ b/indra/cmake/BuildVersion.cmake
@@ -18,7 +18,7 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
find_program(MERCURIAL hg)
if (DEFINED MERCURIAL)
execute_process(
- COMMAND ${MERCURIAL} parents --template "{rev}"
+ COMMAND ${MERCURIAL} log -r tip --template "{p1rev}"
OUTPUT_VARIABLE VIEWER_VERSION_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 246b9680e8..10a23ea068 100755
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES
Audio.cmake
BerkeleyDB.cmake
Boost.cmake
+ BuildVersion.cmake
CARes.cmake
CMakeCopyIfDifferent.cmake
ConfigurePkgConfig.cmake
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 29ab4b1710..1b211ca7b9 100755
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -20,6 +20,7 @@ if(WINDOWS)
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(vivox_files
SLVoice.exe
+ ca-bundle.crt
libsndfile-1.dll
vivoxplatform.dll
vivoxsdk.dll
@@ -195,6 +196,7 @@ elseif(DARWIN)
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(vivox_files
SLVoice
+ ca-bundle.crt
libsndfile.dylib
libvivoxoal.dylib
libortp.dylib
@@ -241,6 +243,7 @@ elseif(LINUX)
libvivoxplatform.so
libvivoxsdk.so
SLVoice
+ # ca-bundle.crt #No cert for linux. It is actually still 3.2SDK.
)
# *TODO - update this to use LIBS_PREBUILT_DIR and LL_ARCH_DIR variables
# or ARCH_PREBUILT_DIRS
diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake
index b70aa6b6ee..73ef59b18f 100755
--- a/indra/cmake/DragDrop.cmake
+++ b/indra/cmake/DragDrop.cmake
@@ -1,20 +1,20 @@
# -*- cmake -*-
-set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
+ set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
-if (OS_DRAG_DROP)
+ if (OS_DRAG_DROP)
- if (WINDOWS)
- add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
- endif (WINDOWS)
+ if (WINDOWS)
+ add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
+ endif (WINDOWS)
- if (DARWIN)
- add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
- endif (DARWIN)
+ if (DARWIN)
+ add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
+ endif (DARWIN)
- if (LINUX)
- add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
- endif (LINUX)
+ if (LINUX)
+ add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
+ endif (LINUX)
-endif (OS_DRAG_DROP)
+ endif (OS_DRAG_DROP)
diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake
index 44f81ce332..8b7f01d20b 100755
--- a/indra/cmake/Havok.cmake
+++ b/indra/cmake/Havok.cmake
@@ -12,14 +12,14 @@ set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
if (LL_DEBUG_HAVOK)
- if (WIN32)
- # Always link relwithdebinfo to havok-hybrid on windows.
- set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
- else (WIN32)
- set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
- endif (WIN32)
+ if (WIN32)
+ # Always link relwithdebinfo to havok-hybrid on windows.
+ set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
+ else (WIN32)
+ set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
+ endif (WIN32)
else (LL_DEBUG_HAVOK)
- set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
+ set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
endif (LL_DEBUG_HAVOK)
set(HAVOK_LIBS
@@ -51,14 +51,14 @@ unset(HK_RELWITHDEBINFO_LIBRARIES)
# *TODO: Figure out why we need to extract like this...
foreach(HAVOK_LIB ${HAVOK_LIBS})
- find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
- find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
- find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
-
- if(LINUX)
- set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
- set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
- set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
+ find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
+ find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
+ find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
+
+ if(LINUX)
+ set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
+ set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
+ set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
# Try to avoid extracting havok library each time we run cmake.
if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted")
@@ -77,35 +77,35 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})
if(DEBUG_PREBUILT)
MESSAGE(STATUS "${cmd} ${debug_dir}")
endif(DEBUG_PREBUILT)
- exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
if(DEBUG_PREBUILT)
MESSAGE(STATUS "${cmd} ${release_dir}")
endif(DEBUG_PREBUILT)
- exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
if(DEBUG_PREBUILT)
MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}")
endif(DEBUG_PREBUILT)
- exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
- set(cmd "ar")
- set(arg " -xv")
- set(arg "${arg} ../lib${HAVOK_LIB}.a")
+ set(cmd "ar")
+ set(arg " -xv")
+ set(arg "${arg} ../lib${HAVOK_LIB}.a")
if(DEBUG_PREBUILT)
MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}")
endif(DEBUG_PREBUILT)
- exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
if(DEBUG_PREBUILT)
MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}")
endif(DEBUG_PREBUILT)
- exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
if(DEBUG_PREBUILT)
MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}")
endif(DEBUG_PREBUILT)
- exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
# Just assume success for now.
set(havok_${HAVOK_LIB}_extracted 0)
@@ -113,9 +113,9 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})
endif(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
- file(GLOB extracted_debug "${debug_dir}/*.o")
- file(GLOB extracted_release "${release_dir}/*.o")
- file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
+ file(GLOB extracted_debug "${debug_dir}/*.o")
+ file(GLOB extracted_release "${release_dir}/*.o")
+ file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
if(DEBUG_PREBUILT)
MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o")
@@ -123,15 +123,15 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})
MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
endif(DEBUG_PREBUILT)
- list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
- list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
- list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
- else(LINUX)
- # Win32
- list(APPEND HK_DEBUG_LIBRARIES ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
- list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
- list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
- endif (LINUX)
+ list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
+ list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
+ list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
+ else(LINUX)
+ # Win32
+ list(APPEND HK_DEBUG_LIBRARIES ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
+ list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
+ list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
+ endif (LINUX)
endforeach(HAVOK_LIB)
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake
index ab39cbb6be..0d87ff579a 100755
--- a/indra/cmake/LLPrimitive.cmake
+++ b/indra/cmake/LLPrimitive.cmake
@@ -2,6 +2,8 @@
# these should be moved to their own cmake file
include(Prebuilt)
+include(Boost)
+
use_prebuilt_binary(colladadom)
use_prebuilt_binary(pcre)
use_prebuilt_binary(libxml)
@@ -15,10 +17,7 @@ if (WINDOWS)
optimized llprimitive
debug libcollada14dom22-d
optimized libcollada14dom22
- debug libboost_filesystem-mt-gd
- optimized libboost_filesystem-mt
- debug libboost_system-mt-gd
- optimized libboost_system-mt
+ ${BOOST_SYSTEM_LIBRARIES}
)
else (WINDOWS)
set(LLPRIMITIVE_LIBRARIES
diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake
index ae71ee4c0d..868922451f 100755
--- a/indra/cmake/LLRender.cmake
+++ b/indra/cmake/LLRender.cmake
@@ -11,8 +11,8 @@ set(LLRENDER_INCLUDE_DIRS
if (BUILD_HEADLESS)
set(LLRENDER_HEADLESS_LIBRARIES
- llrenderheadless
- )
+ llrenderheadless
+ )
endif (BUILD_HEADLESS)
set(LLRENDER_LIBRARIES
llrender
diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake
index 0def507e65..ad732ef650 100755
--- a/indra/cmake/LLWindow.cmake
+++ b/indra/cmake/LLWindow.cmake
@@ -33,10 +33,10 @@ set(LLWINDOW_INCLUDE_DIRS
if (BUILD_HEADLESS)
set(LLWINDOW_HEADLESS_LIBRARIES
- llwindowheadless
- )
+ llwindowheadless
+ )
endif (BUILD_HEADLESS)
-set(LLWINDOW_LIBRARIES
- llwindow
- )
+ set(LLWINDOW_LIBRARIES
+ llwindow
+ )
diff --git a/indra/cmake/VisualLeakDetector.cmake b/indra/cmake/VisualLeakDetector.cmake
index 27e93e28bb..6a20148b47 100755
--- a/indra/cmake/VisualLeakDetector.cmake
+++ b/indra/cmake/VisualLeakDetector.cmake
@@ -1,12 +1,12 @@
# -*- cmake -*-
-set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
+ set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
-if (INCLUDE_VLD_CMAKE)
+ if (INCLUDE_VLD_CMAKE)
- if (WINDOWS)
- add_definitions(-DINCLUDE_VLD=1)
- endif (WINDOWS)
+ if (WINDOWS)
+ add_definitions(-DINCLUDE_VLD=1)
+ endif (WINDOWS)
-endif (INCLUDE_VLD_CMAKE)
+ endif (INCLUDE_VLD_CMAKE)
diff --git a/indra/lib/python/indra/util/llversion.py b/indra/lib/python/indra/util/llversion.py
deleted file mode 100755
index ba6f567b60..0000000000
--- a/indra/lib/python/indra/util/llversion.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env python
-"""\
-@file llversion.py
-@brief Parses llcommon/llversionserver.h and llcommon/llversionviewer.h
- for the version string and channel string.
- Parses hg info for branch and revision.
-
-$LicenseInfo:firstyear=2006&license=mit$
-
-Copyright (c) 2006-2009, Linden Research, Inc.
-
-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.
-$/LicenseInfo$
-"""
-
-import re, sys, os, subprocess
-
-# Methods for gathering version information from
-# llversionviewer.h and llversionserver.h
-
-def get_src_root():
- indra_lib_python_indra_path = os.path.dirname(__file__)
- return os.path.abspath(os.path.realpath(indra_lib_python_indra_path + "/../../../../../"))
-
-def get_version_file_contents(version_type):
- filepath = get_src_root() + '/indra/llcommon/llversion%s.h' % version_type
- file = open(filepath,"r")
- file_str = file.read()
- file.close()
- return file_str
-
-def get_version(version_type):
- file_str = get_version_file_contents(version_type)
- m = re.search('const S32 LL_VERSION_MAJOR = (\d+);', file_str)
- VER_MAJOR = m.group(1)
- m = re.search('const S32 LL_VERSION_MINOR = (\d+);', file_str)
- VER_MINOR = m.group(1)
- m = re.search('const S32 LL_VERSION_PATCH = (\d+);', file_str)
- VER_PATCH = m.group(1)
- m = re.search('const S32 LL_VERSION_BUILD = (\d+);', file_str)
- VER_BUILD = m.group(1)
- version = "%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s" % locals()
- return version
-
-def get_channel(version_type):
- file_str = get_version_file_contents(version_type)
- m = re.search('const char \* const LL_CHANNEL = "(.+)";', file_str)
- return m.group(1)
-
-def get_viewer_version():
- return get_version('viewer')
-
-def get_server_version():
- return get_version('server')
-
-def get_viewer_channel():
- return get_channel('viewer')
-
-def get_server_channel():
- return get_channel('server')
-
-# Methods for gathering hg information
-def get_hg_repo():
- child = subprocess.Popen(["hg","showconfig","paths.default"], stdout=subprocess.PIPE)
- output, error = child.communicate()
- status = child.returncode
- if status:
- print >> sys.stderr, error
- sys.exit(1)
- if not output:
- print >> sys.stderr, 'ERROR: cannot find repo we cloned from'
- sys.exit(1)
- return output
-
-def get_hg_changeset():
- # The right thing to do would be to use the *global* revision id:
- # "hg id -i"
- # For the moment though, we use the parent revision:
- child = subprocess.Popen(["hg","parents","--template","{rev}"], stdout=subprocess.PIPE)
- output, error = child.communicate()
- status = child.returncode
- if status:
- print >> sys.stderr, error
- sys.exit(1)
- lines = output.splitlines()
- if len(lines) > 1:
- print >> sys.stderr, 'ERROR: working directory has %d parents' % len(lines)
- return lines[0]
-
-def using_hg():
- return os.path.isdir(os.path.join(get_src_root(), '.hg'))
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index 41b92b00e0..c0fc1b2be0 100755
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -26,6 +26,10 @@ include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLXML_SYSTEM_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(linux_crash_logger_SOURCE_FILES
linux_crash_logger.cpp
diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
index 8a17819083..93c2f15a53 100644
--- a/indra/llappearance/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -597,19 +597,31 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);
scaled_normals[vert_index_mesh].add(norm);
norm = scaled_normals[vert_index_mesh];
+
+ // guard against degenerate input data before we create NaNs below!
+ //
norm.normalize3fast();
normals[vert_index_mesh] = norm;
// calculate new binormals
LLVector4a binorm = mMorphData->mBinormals[vert_index_morph];
+
+ // guard against degenerate input data before we create NaNs below!
+ //
+ if (!binorm.isFinite3() || (binorm.dot3(binorm).getF32() <= F_APPROXIMATELY_ZERO))
+ {
+ binorm.set(1,0,0,1);
+ }
+
binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);
scaled_binormals[vert_index_mesh].add(binorm);
LLVector4a tangent;
tangent.setCross3(scaled_binormals[vert_index_mesh], norm);
LLVector4a& normalized_binormal = binormals[vert_index_mesh];
- normalized_binormal.setCross3(norm, tangent);
+
+ normalized_binormal.setCross3(norm, tangent);
normalized_binormal.normalize3fast();
-
+
tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight;
}
diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp
index 45fc3186f4..e9b74b8f41 100644
--- a/indra/llaudio/llaudioengine_fmodex.cpp
+++ b/indra/llaudio/llaudioengine_fmodex.cpp
@@ -67,7 +67,7 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
{
if(result == FMOD_OK)
return false;
- llwarns << string << " Error: " << FMOD_ErrorString(result) << llendl;
+ lldebugs << string << " Error: " << FMOD_ErrorString(result) << llendl;
return true;
}
@@ -258,19 +258,29 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
int r_numbuffers, r_samplerate, r_channels, r_bits;
unsigned int r_bufferlength;
- char r_name[256];
mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL;
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_numbuffers=" << r_numbuffers << LL_ENDL;
+
mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits);
- mSystem->getDriverInfo(0, r_name, 255, 0);
- r_name[255] = '\0';
- int latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate);
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL;
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_channels=" << r_channels << LL_ENDL;
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bits =" << r_bits << LL_ENDL;
+
+ char r_name[512];
+ mSystem->getDriverInfo(0, r_name, 511, 0);
+ r_name[511] = '\0';
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_name=\"" << r_name << "\"" << LL_ENDL;
- LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
- << "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n"
- << "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
+ int latency = 100; // optimistic default - i suspect if sample rate is 0, everything breaks.
+ if ( r_samplerate != 0 )
+ latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate);
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): latency=" << latency << "ms" << LL_ENDL;
mInited = true;
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): initialization complete." << LL_ENDL;
+
return true;
}
@@ -310,8 +320,8 @@ void LLAudioEngine_FMODEX::shutdown()
llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;
if ( mSystem ) // speculative fix for MAINT-2657
{
- mSystem->close();
- mSystem->release();
+ mSystem->close();
+ mSystem->release();
}
llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl;
diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h
index 719b0ecbf2..ec58f76f5f 100755
--- a/indra/llaudio/llwindgen.h
+++ b/indra/llaudio/llwindgen.h
@@ -57,7 +57,7 @@ public:
const U32 getInputSamplingRate() { return mInputSamplingRate; }
const F32 getNextSample();
const F32 getClampedSample(bool clamp, F32 sample);
-
+
// newbuffer = the buffer passed from the previous DSP unit.
// numsamples = length in samples-per-channel at this mix time.
// NOTE: generates L/R interleaved stereo
@@ -133,11 +133,11 @@ public:
MIXBUFFERFORMAT_T sample_left = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample - (F32)sample_right);
*cursamplep = sample_left;
- ++cursamplep;
+ ++cursamplep;
*cursamplep = sample_right;
- ++cursamplep;
+ ++cursamplep;
+ }
}
- }
return newbuffer;
}
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index c6da205815..67a98d5fb8 100755
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -986,9 +986,9 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
}
llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl;
- // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
+ // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK);
- // *TODO: Translate the signals/exceptions into cross-platform stuff
+ // *TODO: Translate the signals/exceptions into cross-platform stuff
// Windows implementation
llinfos << "Entering Windows Exception Handler..." << llendl;
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index d1c44c9403..a0802c6adf 100755
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -226,9 +226,7 @@ void LLVolatileAPRPool::clearVolatileAPRPool()
llassert_always(mNumActiveRef > 0) ;
}
- //paranoia check if the pool is jammed.
- //will remove the check before going to release.
- llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
+ llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
}
BOOL LLVolatileAPRPool::isFull()
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index 7542a8dece..5d2fccc5ba 100755
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -63,7 +63,7 @@ public:
// For normal names, returns "James Linden (james.linden)"
// When display names are disabled returns just "James Linden"
std::string getCompleteName() const;
-
+
// Returns "James Linden" or "bobsmith123 Resident" for backwards
// compatibility with systems like voice and muting
// *TODO: Eliminate this in favor of username only
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index a629f71d4b..baaddcaed1 100755
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -60,7 +60,7 @@ bool LLCoros::cleanup(const LLSD&)
// since last tick?
if (mi->second->exited())
{
- LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
+ LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
// The erase() call will invalidate its passed iterator value --
// so increment mi FIRST -- but pass its original value to
// erase(). This is what postincrement is all about.
@@ -94,7 +94,7 @@ std::string LLCoros::generateDistinctName(const std::string& prefix) const
{
if (mCoros.find(name) == mCoros.end())
{
- LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
+ LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
return name;
}
}
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 9b0141eb76..d2af004cde 100755
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -201,10 +201,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message)
{
- llutf16string utf16str =
- wstring_to_utf16str(utf8str_to_wstring(message));
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
+ LL_WINDOWS_OUTPUT_DEBUG(message);
}
};
#endif
@@ -1401,5 +1398,27 @@ namespace LLError
{
sIndex = 0 ;
}
+
+#if LL_WINDOWS
+ void LLOutputDebugUTF8(const std::string& s)
+ {
+ // Be careful when calling OutputDebugString as it throws DBG_PRINTEXCEPTION_C
+ // which works just fine under the windows debugger, but can cause users who
+ // have enabled SEHOP exception chain validation to crash due to interactions
+ // between the Win 32-bit exception handling and boost coroutine fiber stacks. BUG-2707
+ //
+ if (IsDebuggerPresent())
+ {
+ // Need UTF16 for Unicode OutputDebugString
+ //
+ if (s.size())
+ {
+ OutputDebugString(utf8str_to_utf16str(s).c_str());
+ OutputDebugString(TEXT("\n"));
+ }
+ }
+ }
+#endif
+
}
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index b65b410153..0b723aeb5d 100755
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -34,7 +34,6 @@
#include "llerrorlegacy.h"
#include "stdtypes.h"
-
/** Error Logging Facility
Information for most users:
@@ -199,8 +198,20 @@ namespace LLError
static void clear() ;
static void end(std::ostringstream* _out) ;
};
+
+#if LL_WINDOWS
+ void LLOutputDebugUTF8(const std::string& s);
+#endif
+
}
+#if LL_WINDOWS
+ // Macro accepting a std::string for display in windows debugging console
+ #define LL_WINDOWS_OUTPUT_DEBUG(a) LLError::LLOutputDebugUTF8(a)
+#else
+ #define LL_WINDOWS_OUTPUT_DEBUG(a)
+#endif
+
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
#define llpushcallstacks LLError::LLCallStacks::push(__FUNCTION__, __LINE__)
#define llcallstacks \
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 9b15804e97..024fdd1b4d 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -561,7 +561,7 @@ std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
return mChildren;
}
-// static
+//static
LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
{
return *NamedTimerFactory::instance().getRootTimer();
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 864b6e6975..c3a0f0bfe0 100755
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -438,7 +438,7 @@ llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __
_M_set_buffer(0);
__ret = traits_type::not_eof(__c);
}
- }
+ }
else if (_M_buf_size > 1)
{
// Overflow in 'uncommitted' mode: set _M_writing, set
@@ -496,11 +496,11 @@ bool llstdio_filebuf::_convert_to_external(char_type* __ibuf,
if (__r == codecvt_base::ok || __r == codecvt_base::partial)
__blen = __bend - __buf;
else if (__r == codecvt_base::noconv)
- {
+ {
// Same as the always_noconv case above.
__buf = reinterpret_cast<char*>(__ibuf);
__blen = __ilen;
- }
+ }
else
__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
"conversion error"));
@@ -643,9 +643,9 @@ llstdio_filebuf::int_type llstdio_filebuf::underflow()
_M_ext_end, _M_ext_next,
this->eback(),
this->eback() + __buflen, __iend);
- }
+}
if (__r == codecvt_base::noconv)
- {
+{
size_t __avail = _M_ext_end - _M_ext_buf;
__ilen = std::min(__avail, __buflen);
traits_type::copy(this->eback(),
@@ -806,15 +806,15 @@ std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)
__ret = fwrite(__buf, 1, __buffill, _M_file.file());
}
if (__ret == __buffill)
- {
+ {
__ret += fwrite(reinterpret_cast<const char*>(__s), 1,
__n, _M_file.file());
- }
+ }
if (__ret == __buffill + __n)
{
_M_set_buffer(0);
_M_writing = true;
- }
+}
if (__ret > __buffill)
__ret -= __buffill;
else
@@ -848,7 +848,7 @@ llifstream::llifstream() : _M_filebuf(),
#endif
// explicit
-llifstream::llifstream(const std::string& _Filename,
+llifstream::llifstream(const std::string& _Filename,
ios_base::openmode _Mode) : _M_filebuf(),
#if LL_WINDOWS
std::istream(&_M_filebuf)
@@ -877,7 +877,7 @@ llifstream::llifstream(const char* _Filename,
if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
{
_Myios::setstate(ios_base::failbit);
- }
+}
}
#else
std::istream()
@@ -951,8 +951,8 @@ void llifstream::close()
#else
this->setstate(ios_base::failbit);
#endif
+ }
}
-}
/************** output file stream ********************************/
@@ -1042,7 +1042,7 @@ void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
#if LL_WINDOWS
llutf16string wideName = utf8str_to_utf16str( _Filename );
if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
- {
+{
_Myios::setstate(ios_base::failbit);
}
else
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index 9d70db96ea..d59e68367e 100755
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -35,7 +35,7 @@
* Attempts to mostly mirror the POSIX style IO functions.
*/
-typedef FILE LLFILE;
+typedef FILE LLFILE;
#include <fstream>
#include <sys/stat.h>
@@ -237,7 +237,7 @@ public:
ios_base::openmode _Mode = ios_base::in,
//size_t _Size = static_cast<size_t>(BUFSIZ));
size_t _Size = static_cast<size_t>(1));
-
+
/**
* @brief Create a stream using an open file descriptor.
* @param fd An open file descriptor.
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 3ef7a7e4c1..2f8ea1f3d8 100755
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -403,7 +403,7 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
}
if (mEmitErrors)
{
- llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
+ llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
}
data = LLSD();
return LLSDParser::PARSE_FAILURE;
@@ -484,7 +484,7 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)
{
if (mEmitErrors)
{
- llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
+ llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
}
return LLSDParser::PARSE_FAILURE;
}
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index 6f1e7d46b8..f188865eb0 100755
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -969,10 +969,7 @@ namespace tut
childout.getline(), "ok");
// important to get the implicit flush from std::endl
py.mPy->getWritePipe().get_ostream() << "go" << std::endl;
- for (i = 0; i < timeout && py.mPy->isRunning() && ! childout.contains("\n"); ++i)
- {
- yield();
- }
+ waitfor(*py.mPy);
ensure("script never replied", childout.contains("\n"));
ensure_equals("child didn't ack", childout.getline(), "ack");
ensure_equals("bad child termination", py.mPy->getStatus().mState, LLProcess::EXITED);
diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h
index 0526793d3a..79d0a44551 100755
--- a/indra/llmath/llvector4a.h
+++ b/indra/llmath/llvector4a.h
@@ -46,6 +46,7 @@ class LLRotation;
// of this writing, July 08, 2010) about getting it implemented before you resort to
// LLVector3/LLVector4.
/////////////////////////////////
+class LLVector4a;
LL_ALIGN_PREFIX(16)
class LLVector4a
@@ -236,6 +237,11 @@ public:
// Note that this does not consider zero length vectors!
inline void normalize3fast();
+ // Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed
+ // Same as above except substitutes default vector contents if the vector is non-finite or degenerate due to zero length.
+ //
+ inline void normalize3fast_checked(LLVector4a* d = 0);
+
// Return true if this vector is normalized with respect to x,y,z up to tolerance
inline LLBool32 isNormalized3( F32 tolerance = 1e-3 ) const;
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 3f06e6b99e..14cebfe5aa 100755
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -1392,7 +1392,7 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
pt->mTexT = t;
-
+
// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
// Rotate the point around the circle's center.
@@ -1446,7 +1446,7 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
pt->mTexT = t;
-
+
// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
// Rotate the point around the circle's center.
@@ -1594,7 +1594,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
if (is_sculpted)
- sides = sculpt_size;
+ sides = llmax(sculpt_size, 1);
genNGon(params, sides);
}
@@ -1644,6 +1644,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
mPath[i].mScale.mV[0] = lerp(1,params.getScale().mV[0],t);
mPath[i].mScale.mV[1] = lerp(1,params.getScale().mV[1],t);
mPath[i].mTexT = t;
+
mPath[i].mRot.setQuat(F_PI * params.getTwist() * t,1,0,0);
}
@@ -2079,9 +2080,9 @@ void LLVolume::regen()
createVolumeFaces();
}
-void LLVolume::genBinormals(S32 face)
+void LLVolume::genTangents(S32 face)
{
- mVolumeFaces[face].createBinormals();
+ mVolumeFaces[face].createTangents();
}
LLVolume::~LLVolume()
@@ -2442,6 +2443,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
LLVector4a pos_range;
pos_range.setSub(max_pos, min_pos);
LLVector2 tc_range2 = max_tc - min_tc;
+
LLVector4a tc_range;
tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]);
LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]);
@@ -4392,7 +4394,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
segments.push_back(vertices.size());
#if DEBUG_SILHOUETTE_BINORMALS
vertices.push_back(face.mVertices[j].getPosition());
- vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mBinormal*0.1f);
+ vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f);
normals.push_back(LLVector3(0,0,1));
normals.push_back(LLVector3(0,0,1));
segments.push_back(vertices.size());
@@ -4508,22 +4510,9 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
}
}
-S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
- S32 face,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
-{
- LLVector4a starta, enda;
- starta.load3(start.mV);
- enda.load3(end.mV);
-
- return lineSegmentIntersect(starta, enda, face, intersection, tex_coord, normal, bi_normal);
-
-}
-
-
S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out)
{
S32 hit_face = -1;
@@ -4561,9 +4550,9 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
if (LLLineSegmentBoxIntersect(start, end, box_center, box_size))
{
- if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them
+ if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them
{
- genBinormals(i);
+ genTangents(i);
}
if (isUnique())
@@ -4597,7 +4586,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
LLVector4a intersect = dir;
intersect.mul(closest_t);
intersect.add(start);
- intersection->set(intersect.getF32ptr());
+ *intersection = intersect;
}
@@ -4612,19 +4601,42 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
if (normal!= NULL)
{
- LLVector4* norm = (LLVector4*) face.mNormals;
-
- *normal = ((1.f - a - b) * LLVector3(norm[idx0]) +
- a * LLVector3(norm[idx1]) +
- b * LLVector3(norm[idx2]));
+ LLVector4a* norm = face.mNormals;
+
+ LLVector4a n1,n2,n3;
+ n1 = norm[idx0];
+ n1.mul(1.f-a-b);
+
+ n2 = norm[idx1];
+ n2.mul(a);
+
+ n3 = norm[idx2];
+ n3.mul(b);
+
+ n1.add(n2);
+ n1.add(n3);
+
+ *normal = n1;
}
- if (bi_normal != NULL)
+ if (tangent_out != NULL)
{
- LLVector4* binormal = (LLVector4*) face.mBinormals;
- *bi_normal = ((1.f - a - b) * LLVector3(binormal[idx0]) +
- a * LLVector3(binormal[idx1]) +
- b * LLVector3(binormal[idx2]));
+ LLVector4a* tangents = face.mTangents;
+
+ LLVector4a t1,t2,t3;
+ t1 = tangents[idx0];
+ t1.mul(1.f-a-b);
+
+ t2 = tangents[idx1];
+ t2.mul(a);
+
+ t3 = tangents[idx2];
+ t3.mul(b);
+
+ t1.add(t2);
+ t1.add(t3);
+
+ *tangent_out = t1;
}
}
}
@@ -4637,7 +4649,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
face.createOctree();
}
- LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
+ LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
intersect.traverse(face.mOctree);
if (intersect.mHitFace)
{
@@ -5183,7 +5195,7 @@ LLVolumeFace::LLVolumeFace() :
mNumIndices(0),
mPositions(NULL),
mNormals(NULL),
- mBinormals(NULL),
+ mTangents(NULL),
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
@@ -5206,7 +5218,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mNumIndices(0),
mPositions(NULL),
mNormals(NULL),
- mBinormals(NULL),
+ mTangents(NULL),
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
@@ -5264,15 +5276,15 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
}
- if (src.mBinormals)
+ if (src.mTangents)
{
- allocateBinormals(src.mNumVertices);
- LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size);
+ allocateTangents(src.mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size);
}
else
{
- ll_aligned_free_16(mBinormals);
- mBinormals = NULL;
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
}
if (src.mWeights)
@@ -5316,8 +5328,8 @@ void LLVolumeFace::freeData()
mTexCoords = NULL;
ll_aligned_free_16(mIndices);
mIndices = NULL;
- ll_aligned_free_16(mBinormals);
- mBinormals = NULL;
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
ll_aligned_free_16(mWeights);
mWeights = NULL;
@@ -5897,7 +5909,7 @@ void LLVolumeFace::cacheOptimize()
}
LLVector4a* binorm = NULL;
- if (mBinormals)
+ if (mTangents)
{
binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
}
@@ -5922,9 +5934,9 @@ void LLVolumeFace::cacheOptimize()
{
wght[cur_idx] = mWeights[idx];
}
- if (mBinormals)
+ if (mTangents)
{
- binorm[cur_idx] = mBinormals[idx];
+ binorm[cur_idx] = mTangents[idx];
}
cur_idx++;
@@ -5940,13 +5952,13 @@ void LLVolumeFace::cacheOptimize()
ll_aligned_free_16(mNormals);
ll_aligned_free_16(mTexCoords);
ll_aligned_free_16(mWeights);
- ll_aligned_free_16(mBinormals);
+ ll_aligned_free_16(mTangents);
mPositions = pos;
mNormals = norm;
mTexCoords = tc;
mWeights = wght;
- mBinormals = binorm;
+ mTangents = binorm;
//std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
//llinfos << result << llendl;
@@ -6027,7 +6039,7 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs)
{
llswap(rhs.mPositions, mPositions);
llswap(rhs.mNormals, mNormals);
- llswap(rhs.mBinormals, mBinormals);
+ llswap(rhs.mTangents, mTangents);
llswap(rhs.mTexCoords, mTexCoords);
llswap(rhs.mIndices,mIndices);
llswap(rhs.mNumVertices, mNumVertices);
@@ -6116,22 +6128,11 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
corners[2].mTexCoord=swap;
}
- LLVector4a binormal;
-
- calc_binormal_from_triangle( binormal,
- corners[0].getPosition(), corners[0].mTexCoord,
- corners[1].getPosition(), corners[1].mTexCoord,
- corners[2].getPosition(), corners[2].mTexCoord);
-
- binormal.normalize3fast();
-
S32 size = (grid_size+1)*(grid_size+1);
resizeVertices(size);
- allocateBinormals(size);
-
+
LLVector4a* pos = (LLVector4a*) mPositions;
LLVector4a* norm = (LLVector4a*) mNormals;
- LLVector4a* binorm = (LLVector4a*) mBinormals;
LLVector2* tc = (LLVector2*) mTexCoords;
for(int gx = 0;gx<grid_size+1;gx++)
@@ -6150,8 +6151,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
*pos++ = newVert.getPosition();
*norm++ = baseVert.getNormal();
*tc++ = newVert.mTexCoord;
- *binorm++ = binormal;
-
+
if (gx == 0 && gy == 0)
{
min = newVert.getPosition();
@@ -6227,8 +6227,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
{
resizeVertices(num_vertices+1);
- allocateBinormals(num_vertices+1);
-
+
if (!partial_build)
{
resizeIndices(num_indices+3);
@@ -6237,8 +6236,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
else
{
resizeVertices(num_vertices);
- allocateBinormals(num_vertices);
-
+
if (!partial_build)
{
resizeIndices(num_indices);
@@ -6272,8 +6270,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
LLVector2* tc = (LLVector2*) mTexCoords;
LLVector4a* pos = (LLVector4a*) mPositions;
LLVector4a* norm = (LLVector4a*) mNormals;
- LLVector4a* binorm = (LLVector4a*) mBinormals;
-
+
// Copy the vertices into the array
for (S32 i = 0; i < num_vertices; i++)
{
@@ -6309,31 +6306,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
cuv = (min_uv + max_uv)*0.5f;
- LLVector4a binormal;
- calc_binormal_from_triangle(binormal,
- *mCenter, cuv,
- pos[0], tc[0],
- pos[1], tc[1]);
- binormal.normalize3fast();
-
- LLVector4a normal;
- LLVector4a d0, d1;
-
-
- d0.setSub(*mCenter, pos[0]);
- d1.setSub(*mCenter, pos[1]);
-
- if (mTypeMask & TOP_MASK)
- {
- normal.setCross3(d0, d1);
- }
- else
- {
- normal.setCross3(d1, d0);
- }
-
- normal.normalize3fast();
-
VertexData vd;
vd.setPosition(*mCenter);
vd.mTexCoord = cuv;
@@ -6342,15 +6314,10 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
{
pos[num_vertices] = *mCenter;
tc[num_vertices] = cuv;
+
num_vertices++;
}
- for (S32 i = 0; i < num_vertices; i++)
- {
- binorm[i].load4a(binormal.getF32ptr());
- norm[i].load4a(normal.getF32ptr());
- }
-
if (partial_build)
{
return TRUE;
@@ -6585,63 +6552,68 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
}
-
+
+ LLVector4a d0,d1;
+
+ d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
+ d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]);
+
+ LLVector4a normal;
+ normal.setCross3(d0,d1);
+
+ if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ normal.normalize3fast();
+ }
+ else
+ { //degenerate, make up a value
+ normal.set(0,0,1);
+ }
+
+ llassert(llfinite(normal.getF32ptr()[0]));
+ llassert(llfinite(normal.getF32ptr()[1]));
+ llassert(llfinite(normal.getF32ptr()[2]));
+
+ llassert(!llisnan(normal.getF32ptr()[0]));
+ llassert(!llisnan(normal.getF32ptr()[1]));
+ llassert(!llisnan(normal.getF32ptr()[2]));
+
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ norm[i].load4a(normal.getF32ptr());
+ }
+
return TRUE;
}
-void LLVolumeFace::createBinormals()
+void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
+ const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent);
+
+void LLVolumeFace::createTangents()
{
- if (!mBinormals)
+ if (!mTangents)
{
- allocateBinormals(mNumVertices);
+ allocateTangents(mNumVertices);
- //generate binormals
- LLVector4a* pos = mPositions;
- LLVector2* tc = (LLVector2*) mTexCoords;
- LLVector4a* binorm = (LLVector4a*) mBinormals;
+ //generate tangents
+ //LLVector4a* pos = mPositions;
+ //LLVector2* tc = (LLVector2*) mTexCoords;
+ LLVector4a* binorm = (LLVector4a*) mTangents;
- LLVector4a* end = mBinormals+mNumVertices;
+ LLVector4a* end = mTangents+mNumVertices;
while (binorm < end)
{
(*binorm++).clear();
}
- binorm = mBinormals;
-
- for (U32 i = 0; i < mNumIndices/3; i++)
- { //for each triangle
- const U16& i0 = mIndices[i*3+0];
- const U16& i1 = mIndices[i*3+1];
- const U16& i2 = mIndices[i*3+2];
-
- //calculate binormal
- LLVector4a binormal;
- calc_binormal_from_triangle(binormal,
- pos[i0], tc[i0],
- pos[i1], tc[i1],
- pos[i2], tc[i2]);
-
+ binorm = mTangents;
- //add triangle normal to vertices
- binorm[i0].add(binormal);
- binorm[i1].add(binormal);
- binorm[i2].add(binormal);
+ CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
- //even out quad contributions
- if (i % 2 == 0)
- {
- binorm[i2].add(binormal);
- }
- else
- {
- binorm[i1].add(binormal);
- }
- }
-
- //normalize binormals
+ //normalize tangents
for (U32 i = 0; i < mNumVertices; i++)
{
- binorm[i].normalize3fast();
+ //binorm[i].normalize3fast();
//bump map/planar projection code requires normals to be normalized
mNormals[i].normalize3fast();
}
@@ -6652,10 +6624,10 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
{
ll_aligned_free_16(mPositions);
ll_aligned_free_16(mNormals);
- ll_aligned_free_16(mBinormals);
+ ll_aligned_free_16(mTangents);
ll_aligned_free_16(mTexCoords);
- mBinormals = NULL;
+ mTangents = NULL;
if (num_verts)
{
@@ -6705,9 +6677,9 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
ll_assert_aligned(mTexCoords,16);
- //just clear binormals
- ll_aligned_free_16(mBinormals);
- mBinormals = NULL;
+ //just clear tangents
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
mPositions[mNumVertices] = pos;
mNormals[mNumVertices] = norm;
@@ -6716,10 +6688,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
mNumVertices++;
}
-void LLVolumeFace::allocateBinormals(S32 num_verts)
+void LLVolumeFace::allocateTangents(S32 num_verts)
{
- ll_aligned_free_16(mBinormals);
- mBinormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
+ ll_aligned_free_16(mTangents);
+ mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
}
void LLVolumeFace::allocateWeights(S32 num_verts)
@@ -6956,7 +6928,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0)
{
-
pos[cur_vertex].load3(mesh[i].mPos.mV);
tc[cur_vertex] = LLVector2(ss,tt);
@@ -6987,7 +6958,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
}
-
//get bounding box for this side
LLVector4a& face_min = mExtents[0];
LLVector4a& face_max = mExtents[1];
@@ -7093,6 +7063,14 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
n[1]->add(c);
n[2]->add(c);
+ llassert(llfinite(c.getF32ptr()[0]));
+ llassert(llfinite(c.getF32ptr()[1]));
+ llassert(llfinite(c.getF32ptr()[2]));
+
+ llassert(!llisnan(c.getF32ptr()[0]));
+ llassert(!llisnan(c.getF32ptr()[1]));
+ llassert(!llisnan(c.getF32ptr()[2]));
+
//even out quad contributions
n[i%2+1]->add(c);
}
@@ -7231,53 +7209,101 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
return TRUE;
}
-// Finds binormal based on three vertices with texture coordinates.
-// Fills in dummy values if the triangle has degenerate texture coordinates.
-void calc_binormal_from_triangle(LLVector4a& binormal,
-
- const LLVector4a& pos0,
- const LLVector2& tex0,
- const LLVector4a& pos1,
- const LLVector2& tex1,
- const LLVector4a& pos2,
- const LLVector2& tex2)
-{
- LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] );
- LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] );
- LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] );
-
- LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] );
- LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] );
- LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] );
-
- LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] );
- LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] );
- LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] );
-
- LLVector4a lhs, rhs;
-
- LLVector4a r0;
- lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2);
- r0.setCross3(lhs, rhs);
+//adapted from Lengyel, Eric. Computing Tangent Space Basis Vectors for an Arbitrary Mesh. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
+void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
+ const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
+{
+ //LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
+ LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
+
+ LLVector4a* tan2 = tan1 + vertexCount;
+
+ memset(tan1, 0, vertexCount*2*sizeof(LLVector4a));
+
+ for (U32 a = 0; a < triangleCount; a++)
+ {
+ U32 i1 = *index_array++;
+ U32 i2 = *index_array++;
+ U32 i3 = *index_array++;
+
+ const LLVector4a& v1 = vertex[i1];
+ const LLVector4a& v2 = vertex[i2];
+ const LLVector4a& v3 = vertex[i3];
+
+ const LLVector2& w1 = texcoord[i1];
+ const LLVector2& w2 = texcoord[i2];
+ const LLVector2& w3 = texcoord[i3];
+
+ const F32* v1ptr = v1.getF32ptr();
+ const F32* v2ptr = v2.getF32ptr();
+ const F32* v3ptr = v3.getF32ptr();
- LLVector4a r1;
- lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2);
- r1.setCross3(lhs, rhs);
-
- LLVector4a r2;
- lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2);
- r2.setCross3(lhs, rhs);
+ float x1 = v2ptr[0] - v1ptr[0];
+ float x2 = v3ptr[0] - v1ptr[0];
+ float y1 = v2ptr[1] - v1ptr[1];
+ float y2 = v3ptr[1] - v1ptr[1];
+ float z1 = v2ptr[2] - v1ptr[2];
+ float z2 = v3ptr[2] - v1ptr[2];
+
+ float s1 = w2.mV[0] - w1.mV[0];
+ float s2 = w3.mV[0] - w1.mV[0];
+ float t1 = w2.mV[1] - w1.mV[1];
+ float t2 = w3.mV[1] - w1.mV[1];
+
+ F32 rd = s1*t2-s2*t1;
+
+ float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero
+
+ llassert(llfinite(r));
+ llassert(!llisnan(r));
+
+ LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+ LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+
+ tan1[i1].add(sdir);
+ tan1[i2].add(sdir);
+ tan1[i3].add(sdir);
+
+ tan2[i1].add(tdir);
+ tan2[i2].add(tdir);
+ tan2[i3].add(tdir);
+ }
+
+ for (U32 a = 0; a < vertexCount; a++)
+ {
+ LLVector4a n = normal[a];
+
+ const LLVector4a& t = tan1[a];
+
+ LLVector4a ncrosst;
+ ncrosst.setCross3(n,t);
+
+ // Gram-Schmidt orthogonalize
+ n.mul(n.dot3(t).getF32());
+
+ LLVector4a tsubn;
+ tsubn.setSub(t,n);
+
+ if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ tsubn.normalize3fast();
+
+ // Calculate handedness
+ F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f;
+
+ tsubn.getF32ptr()[3] = handedness;
- if( r0[VX] && r1[VX] && r2[VX] )
- {
- binormal.set(
- -r0[VZ] / r0[VX],
- -r1[VZ] / r1[VX],
- -r2[VZ] / r2[VX]);
- // binormal.normVec();
- }
- else
- {
- binormal.set( 0, 1 , 0 );
- }
+ tangent[a] = tsubn;
+ }
+ else
+ { //degenerate, make up a value
+ tangent[a].set(0,0,1,1);
+ }
+ }
+
+ ll_aligned_free_16(tan1);
}
+
+
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index c845556557..164b8d6652 100755
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -844,12 +844,12 @@ private:
public:
BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
- void createBinormals();
+ void createTangents();
void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);
void resizeVertices(S32 num_verts);
- void allocateBinormals(S32 num_verts);
+ void allocateTangents(S32 num_verts);
void allocateWeights(S32 num_verts);
void resizeIndices(S32 num_indices);
void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
@@ -916,7 +916,7 @@ public:
LLVector4a* mPositions;
LLVector4a* mNormals;
- LLVector4a* mBinormals;
+ LLVector4a* mTangents;
LLVector2* mTexCoords;
U16* mIndices;
@@ -980,7 +980,7 @@ public:
void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
void regen();
- void genBinormals(S32 face);
+ void genTangents(S32 face);
BOOL isConvex() const;
BOOL isCap(S32 face);
@@ -1008,21 +1008,14 @@ public:
//get the face index of the face that intersects with the given line segment at the point
//closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
//Line segment must be in volume space.
- S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
- S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face = 1,
- LLVector3* intersection = NULL,
- LLVector2* tex_coord = NULL,
- LLVector3* normal = NULL,
- LLVector3* bi_normal = NULL);
-
LLFaceID generateFaceMask();
BOOL isFaceMaskValid(LLFaceID face_mask);
@@ -1081,21 +1074,12 @@ public:
std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
-void calc_binormal_from_triangle(
- LLVector4a& binormal,
- const LLVector4a& pos0,
- const LLVector2& tex0,
- const LLVector4a& pos1,
- const LLVector2& tex1,
- const LLVector4a& pos2,
- const LLVector2& tex2);
-
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size);
-BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
- F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
+//BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
+// F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
F32& intersection_a, F32& intersection_b, F32& intersection_t);
diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp
index cc83cb7235..0728b49c1f 100755
--- a/indra/llmath/llvolumeoctree.cpp
+++ b/indra/llmath/llvolumeoctree.cpp
@@ -94,14 +94,14 @@ void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTria
LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
const LLVolumeFace* face, F32* closest_t,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
: mFace(face),
mStart(start),
mDir(dir),
mIntersection(intersection),
mTexCoord(tex_coord),
mNormal(normal),
- mBinormal(bi_normal),
+ mTangent(tangent),
mClosestT(closest_t),
mHitFace(false)
{
@@ -112,13 +112,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
- /*const F32* start = mStart.getF32();
- const F32* end = mEnd.getF32();
- const F32* center = vl->mBounds[0].getF32();
- const F32* size = vl->mBounds[1].getF32();*/
-
- //if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
- if (LLLineSegmentBoxIntersect(mStart.getF32ptr(), mEnd.getF32ptr(), vl->mBounds[0].getF32ptr(), vl->mBounds[1].getF32ptr()))
+ if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
{
node->accept(this);
for (S32 i = 0; i < node->getChildCount(); ++i)
@@ -152,34 +146,60 @@ void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* n
LLVector4a intersect = mDir;
intersect.mul(*mClosestT);
intersect.add(mStart);
- mIntersection->set(intersect.getF32ptr());
+ *mIntersection = intersect;
}
+ U32 idx0 = tri->mIndex[0];
+ U32 idx1 = tri->mIndex[1];
+ U32 idx2 = tri->mIndex[2];
if (mTexCoord != NULL)
{
LLVector2* tc = (LLVector2*) mFace->mTexCoords;
- *mTexCoord = ((1.f - a - b) * tc[tri->mIndex[0]] +
- a * tc[tri->mIndex[1]] +
- b * tc[tri->mIndex[2]]);
+ *mTexCoord = ((1.f - a - b) * tc[idx0] +
+ a * tc[idx1] +
+ b * tc[idx2]);
}
if (mNormal != NULL)
{
- LLVector4* norm = (LLVector4*) mFace->mNormals;
-
- *mNormal = ((1.f - a - b) * LLVector3(norm[tri->mIndex[0]]) +
- a * LLVector3(norm[tri->mIndex[1]]) +
- b * LLVector3(norm[tri->mIndex[2]]));
+ LLVector4a* norm = mFace->mNormals;
+
+ LLVector4a n1,n2,n3;
+ n1 = norm[idx0];
+ n1.mul(1.f-a-b);
+
+ n2 = norm[idx1];
+ n2.mul(a);
+
+ n3 = norm[idx2];
+ n3.mul(b);
+
+ n1.add(n2);
+ n1.add(n3);
+
+ *mNormal = n1;
}
- if (mBinormal != NULL)
+ if (mTangent != NULL)
{
- LLVector4* binormal = (LLVector4*) mFace->mBinormals;
- *mBinormal = ((1.f - a - b) * LLVector3(binormal[tri->mIndex[0]]) +
- a * LLVector3(binormal[tri->mIndex[1]]) +
- b * LLVector3(binormal[tri->mIndex[2]]));
+ LLVector4a* tangents = mFace->mTangents;
+
+ LLVector4a t1,t2,t3;
+ t1 = tangents[idx0];
+ t1.mul(1.f-a-b);
+
+ t2 = tangents[idx1];
+ t2.mul(a);
+
+ t3 = tangents[idx2];
+ t3.mul(b);
+
+ t1.add(t2);
+ t1.add(t3);
+
+ *mTangent = t1;
}
}
}
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index 9ae34a0c4e..80d6ced36d 100755
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -137,16 +137,16 @@ public:
LLVector4a mStart;
LLVector4a mDir;
LLVector4a mEnd;
- LLVector3* mIntersection;
+ LLVector4a* mIntersection;
LLVector2* mTexCoord;
- LLVector3* mNormal;
- LLVector3* mBinormal;
+ LLVector4a* mNormal;
+ LLVector4a* mTangent;
F32* mClosestT;
bool mHitFace;
LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
const LLVolumeFace* face, F32* closest_t,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal);
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
void traverse(const LLOctreeNode<LLVolumeTriangle>* node);
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 6fa2669be6..d43ea5b2cb 100755
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -242,7 +242,7 @@ if (LL_TESTS)
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
- ${GOOGLEMOCK_LIBRARIES}
+ ${GOOGLEMOCK_LIBRARIES}
)
LL_ADD_INTEGRATION_TEST(
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
index 5a67035ed1..7f74247a13 100755
--- a/indra/llmessage/llares.cpp
+++ b/indra/llmessage/llares.cpp
@@ -99,8 +99,7 @@ void LLAres::QueryResponder::queryError(int code)
LLAres::LLAres() :
chan_(NULL),
- mInitSuccess(false),
- mListener(new LLAresListener(this))
+ mInitSuccess(false)
{
if (ares_library_init( ARES_LIB_INIT_ALL ) != ARES_SUCCESS ||
ares_init(&chan_) != ARES_SUCCESS)
@@ -109,6 +108,8 @@ LLAres::LLAres() :
return;
}
+ mListener = boost::shared_ptr< LLAresListener >(new LLAresListener(this));
+
mInitSuccess = true;
}
@@ -161,12 +162,26 @@ void LLAres::getSrvRecords(const std::string &name, SrvResponder *resp)
}
void LLAres::rewriteURI(const std::string &uri, UriRewriteResponder *resp)
-{
- llinfos << "Rewriting " << uri << llendl;
+{
+ if (resp && uri.size())
+ {
+ LLURI* pURI = new LLURI(uri);
+
+ resp->mUri = *pURI;
+
+ delete pURI;
+
+ if (!resp->mUri.scheme().size() || !resp->mUri.hostName().size())
+ {
+ return;
+ }
+
+ //llinfos << "LLAres::rewriteURI (" << uri << ") search: '" << "_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName() << "'" << llendl;
- resp->mUri = LLURI(uri);
- search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(),
- RES_SRV, resp);
+ search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), RES_SRV, resp);
+
+
+ }
}
LLQueryResponder::LLQueryResponder()
diff --git a/indra/llmessage/llareslistener.cpp b/indra/llmessage/llareslistener.cpp
index 58b8a05a9e..0a4effac19 100755
--- a/indra/llmessage/llareslistener.cpp
+++ b/indra/llmessage/llareslistener.cpp
@@ -93,5 +93,12 @@ private:
void LLAresListener::rewriteURI(const LLSD& data)
{
- mAres->rewriteURI(data["uri"], new UriRewriteResponder(data));
+ if (mAres)
+ {
+ mAres->rewriteURI(data["uri"], new UriRewriteResponder(data));
+ }
+ else
+ {
+ llinfos << "LLAresListener::rewriteURI requested without Ares present. Ignoring: " << data << llendl;
+ }
}
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 7bf930aeb0..d6448e83fe 100755
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -300,11 +300,11 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
const F32 TIMEOUT_ADJUSTMENT = 2.0f;
mDetail->mByteAccumulator = 0;
pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT);
- lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl;
- if (mState == STATE_INITIALIZED)
- {
- llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl;
- }
+ lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl;
+ if (mState == STATE_INITIALIZED)
+ {
+ llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl;
+ }
}
switch(mState)
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index 43fac83c57..a32bfa59ce 100755
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -232,7 +232,7 @@ namespace tut
ensureStatusOK();
ensure_equals("echoed result matches", getResult(), sd);
}
-
+
template<> template<>
void HTTPClientTestObject::test<4>()
{
diff --git a/indra/llplugin/slplugin/slplugin-objc.mm b/indra/llplugin/slplugin/slplugin-objc.mm
index a434739350..a5ab1d95c8 100755
--- a/indra/llplugin/slplugin/slplugin-objc.mm
+++ b/indra/llplugin/slplugin/slplugin-objc.mm
@@ -115,7 +115,7 @@ void LLCocoaPlugin::setupGroup()
}
-void LLCocoaPlugin::updateWindows() //SPATTERS give this a better name.
+void LLCocoaPlugin::updateWindows()
{
// NSArray* window_list = [NSApp orderedWindows];
// NSWindow* current_window = [window_list objectAtIndex:0];
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 1768a06a27..0dd13916bf 100755
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -24,6 +24,8 @@ include_directories(SYSTEM
)
set(llprimitive_SOURCE_FILES
+ llmaterialid.cpp
+ llmaterial.cpp
llmaterialtable.cpp
llmediaentry.cpp
llmodel.cpp
@@ -41,6 +43,8 @@ set(llprimitive_HEADER_FILES
CMakeLists.txt
legacy_object_types.h
+ llmaterial.h
+ llmaterialid.h
llmaterialtable.h
llmediaentry.h
llmodel.h
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
new file mode 100644
index 0000000000..cf4c645cfd
--- /dev/null
+++ b/indra/llprimitive/llmaterial.cpp
@@ -0,0 +1,227 @@
+/**
+ * @file llmaterial.cpp
+ * @brief Material definition
+ *
+ * $LicenseInfo:firstyear=2006&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 "linden_common.h"
+
+#include "llmaterial.h"
+
+/**
+ * Materials cap parameters
+ */
+#define MATERIALS_CAP_NORMAL_MAP_FIELD "NormMap"
+#define MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD "NormOffsetX"
+#define MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD "NormOffsetY"
+#define MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD "NormRepeatX"
+#define MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD "NormRepeatY"
+#define MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD "NormRotation"
+
+#define MATERIALS_CAP_SPECULAR_MAP_FIELD "SpecMap"
+#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD "SpecOffsetX"
+#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD "SpecOffsetY"
+#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD "SpecRepeatX"
+#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD "SpecRepeatY"
+#define MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD "SpecRotation"
+
+#define MATERIALS_CAP_SPECULAR_COLOR_FIELD "SpecColor"
+#define MATERIALS_CAP_SPECULAR_EXP_FIELD "SpecExp"
+#define MATERIALS_CAP_ENV_INTENSITY_FIELD "EnvIntensity"
+#define MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD "AlphaMaskCutoff"
+#define MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD "DiffuseAlphaMode"
+
+const LLColor4U LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR(255,255,255,255);
+
+/**
+ * Materials constants
+ */
+
+const F32 MATERIALS_MULTIPLIER = 10000.f;
+
+/**
+ * Helper functions
+ */
+
+template<typename T> T getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
+{
+ if ( (data.has(field)) && (field_type == data[field].type()) )
+ {
+ return (T)data[field];
+ }
+ llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl;
+ return (T)LLSD();
+}
+
+// GCC didn't like the generic form above for some reason
+template<> LLUUID getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
+{
+ if ( (data.has(field)) && (field_type == data[field].type()) )
+ {
+ return data[field].asUUID();
+ }
+ llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl;
+ return LLUUID::null;
+}
+
+/**
+ * LLMaterial class
+ */
+
+const LLMaterial LLMaterial::null;
+
+LLMaterial::LLMaterial()
+ : mNormalOffsetX(0.0f)
+ , mNormalOffsetY(0.0f)
+ , mNormalRepeatX(1.0f)
+ , mNormalRepeatY(1.0f)
+ , mNormalRotation(0.0f)
+ , mSpecularOffsetX(0.0f)
+ , mSpecularOffsetY(0.0f)
+ , mSpecularRepeatX(1.0f)
+ , mSpecularRepeatY(1.0f)
+ , mSpecularRotation(0.0f)
+ , mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR)
+ , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)
+ , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
+ , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+ , mAlphaMaskCutoff(0)
+{
+}
+
+LLMaterial::LLMaterial(const LLSD& material_data)
+{
+ fromLLSD(material_data);
+}
+
+LLSD LLMaterial::asLLSD() const
+{
+ LLSD material_data;
+
+ material_data[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalID;
+ material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = llround(mNormalOffsetX * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = llround(mNormalOffsetY * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = llround(mNormalRepeatX * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = llround(mNormalRepeatY * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = llround(mNormalRotation * MATERIALS_MULTIPLIER);
+
+ material_data[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularID;
+ material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = llround(mSpecularOffsetX * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = llround(mSpecularOffsetY * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = llround(mSpecularRepeatX * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = llround(mSpecularRepeatY * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = llround(mSpecularRotation * MATERIALS_MULTIPLIER);
+
+ material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = mSpecularLightColor.getValue();
+ material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD] = mSpecularLightExponent;
+ material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD] = mEnvironmentIntensity;
+ material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode;
+ material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = mAlphaMaskCutoff;
+
+ return material_data;
+}
+
+void LLMaterial::fromLLSD(const LLSD& material_data)
+{
+ mNormalID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID);
+ mNormalOffsetX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mNormalOffsetY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mNormalRepeatX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mNormalRepeatY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mNormalRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+
+ mSpecularID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID);
+ mSpecularOffsetX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mSpecularOffsetY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mSpecularRepeatX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mSpecularRepeatY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mSpecularRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+
+ mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray));
+ mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD, LLSD::TypeInteger);
+ mEnvironmentIntensity = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD, LLSD::TypeInteger);
+ mDiffuseAlphaMode = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
+ mAlphaMaskCutoff = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD, LLSD::TypeInteger);
+}
+
+bool LLMaterial::isNull() const
+{
+ return (*this == null);
+}
+
+bool LLMaterial::operator == (const LLMaterial& rhs) const
+{
+ return
+ (mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) &&
+ (mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) &&
+ (mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) &&
+ (mSpecularRepeatX == rhs.mSpecularRepeatX) && (mSpecularRepeatY == rhs.mSpecularRepeatY) && (mSpecularRotation == rhs.mSpecularRotation) &&
+ (mSpecularLightColor == rhs.mSpecularLightColor) && (mSpecularLightExponent == rhs.mSpecularLightExponent) &&
+ (mEnvironmentIntensity == rhs.mEnvironmentIntensity) && (mDiffuseAlphaMode == rhs.mDiffuseAlphaMode) && (mAlphaMaskCutoff == rhs.mAlphaMaskCutoff);
+}
+
+bool LLMaterial::operator != (const LLMaterial& rhs) const
+{
+ return !(*this == rhs);
+}
+
+
+U32 LLMaterial::getShaderMask(U32 alpha_mode)
+{ //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation
+ U32 ret = 0;
+
+ //two least significant bits are "diffuse alpha mode"
+ if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT)
+ {
+ ret = alpha_mode;
+ }
+ else
+ {
+ ret = getDiffuseAlphaMode();
+ }
+
+ llassert(ret < SHADER_COUNT);
+
+ //next bit is whether or not specular map is present
+ const U32 SPEC_BIT = 0x4;
+
+ if (getSpecularID().notNull())
+ {
+ ret |= SPEC_BIT;
+ }
+
+ llassert(ret < SHADER_COUNT);
+
+ //next bit is whether or not normal map is present
+ const U32 NORM_BIT = 0x8;
+ if (getNormalID().notNull())
+ {
+ ret |= NORM_BIT;
+ }
+
+ llassert(ret < SHADER_COUNT);
+
+ return ret;
+}
+
+
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
new file mode 100644
index 0000000000..9f52a3f6c1
--- /dev/null
+++ b/indra/llprimitive/llmaterial.h
@@ -0,0 +1,155 @@
+/**
+ * @file llmaterial.h
+ * @brief Material definition
+ *
+ * $LicenseInfo:firstyear=2006&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_LLMATERIAL_H
+#define LL_LLMATERIAL_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "llmaterialid.h"
+#include "llsd.h"
+#include "v4coloru.h"
+#include "llpointer.h"
+#include "llrefcount.h"
+
+class LLMaterial : public LLRefCount
+{
+public:
+
+ typedef enum
+ {
+ DIFFUSE_ALPHA_MODE_NONE = 0,
+ DIFFUSE_ALPHA_MODE_BLEND = 1,
+ DIFFUSE_ALPHA_MODE_MASK = 2,
+ DIFFUSE_ALPHA_MODE_EMISSIVE = 3,
+ DIFFUSE_ALPHA_MODE_DEFAULT = 4,
+ } eDiffuseAlphaMode;
+
+ typedef enum
+ {
+ SHADER_COUNT = 16,
+ 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;
+
+ LLMaterial();
+ LLMaterial(const LLSD& material_data);
+
+ LLSD asLLSD() const;
+ void fromLLSD(const LLSD& material_data);
+
+ const LLUUID& getNormalID() const { return mNormalID; }
+ void setNormalID(const LLUUID& normal_id) { mNormalID = normal_id; }
+ void getNormalOffset(F32& offset_x, F32& offset_y) const { offset_x = mNormalOffsetX; offset_y = mNormalOffsetY; }
+ F32 getNormalOffsetX() const { return mNormalOffsetX; }
+ F32 getNormalOffsetY() const { return mNormalOffsetY; }
+
+ void setNormalOffset(F32 offset_x, F32 offset_y) { mNormalOffsetX = offset_x; mNormalOffsetY = offset_y; }
+ void setNormalOffsetX(F32 offset_x) { mNormalOffsetX = offset_x; }
+ void setNormalOffsetY(F32 offset_y) { mNormalOffsetY = offset_y; }
+
+ void getNormalRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mNormalRepeatX; repeat_y = mNormalRepeatY; }
+ F32 getNormalRepeatX() const { return mNormalRepeatX; }
+ F32 getNormalRepeatY() const { return mNormalRepeatY; }
+
+ void setNormalRepeat(F32 repeat_x, F32 repeat_y) { mNormalRepeatX = repeat_x; mNormalRepeatY = repeat_y; }
+ void setNormalRepeatX(F32 repeat_x) { mNormalRepeatX = repeat_x; }
+ void setNormalRepeatY(F32 repeat_y) { mNormalRepeatY = repeat_y; }
+
+ F32 getNormalRotation() const { return mNormalRotation; }
+ void setNormalRotation(F32 rot) { mNormalRotation = rot; }
+
+ const LLUUID& getSpecularID() const { return mSpecularID; }
+ void setSpecularID(const LLUUID& specular_id) { mSpecularID = specular_id; }
+ void getSpecularOffset(F32& offset_x, F32& offset_y) const { offset_x = mSpecularOffsetX; offset_y = mSpecularOffsetY; }
+ F32 getSpecularOffsetX() const { return mSpecularOffsetX; }
+ F32 getSpecularOffsetY() const { return mSpecularOffsetY; }
+
+ void setSpecularOffset(F32 offset_x, F32 offset_y) { mSpecularOffsetX = offset_x; mSpecularOffsetY = offset_y; }
+ void setSpecularOffsetX(F32 offset_x) { mSpecularOffsetX = offset_x; }
+ void setSpecularOffsetY(F32 offset_y) { mSpecularOffsetY = offset_y; }
+
+ void getSpecularRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mSpecularRepeatX; repeat_y = mSpecularRepeatY; }
+ F32 getSpecularRepeatX() const { return mSpecularRepeatX; }
+ F32 getSpecularRepeatY() const { return mSpecularRepeatY; }
+
+ void setSpecularRepeat(F32 repeat_x, F32 repeat_y) { mSpecularRepeatX = repeat_x; mSpecularRepeatY = repeat_y; }
+ void setSpecularRepeatX(F32 repeat_x) { mSpecularRepeatX = repeat_x; }
+ void setSpecularRepeatY(F32 repeat_y) { mSpecularRepeatY = repeat_y; }
+
+ F32 getSpecularRotation() const { return mSpecularRotation; }
+ void setSpecularRotation(F32 rot) { mSpecularRotation = rot; }
+
+ const LLColor4U getSpecularLightColor() const { return mSpecularLightColor; }
+ void setSpecularLightColor(const LLColor4U& color) { mSpecularLightColor = color; }
+ U8 getSpecularLightExponent() const { return mSpecularLightExponent; }
+ void setSpecularLightExponent(U8 exponent) { mSpecularLightExponent = exponent; }
+ U8 getEnvironmentIntensity() const { return mEnvironmentIntensity; }
+ void setEnvironmentIntensity(U8 intensity) { mEnvironmentIntensity = intensity; }
+ U8 getDiffuseAlphaMode() const { return mDiffuseAlphaMode; }
+ void setDiffuseAlphaMode(U8 alpha_mode) { mDiffuseAlphaMode = alpha_mode; }
+ U8 getAlphaMaskCutoff() const { return mAlphaMaskCutoff; }
+ void setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; }
+
+ bool isNull() const;
+ static const LLMaterial null;
+
+ bool operator == (const LLMaterial& rhs) const;
+ bool operator != (const LLMaterial& rhs) const;
+
+ U32 getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT);
+
+protected:
+ LLUUID mNormalID;
+ F32 mNormalOffsetX;
+ F32 mNormalOffsetY;
+ F32 mNormalRepeatX;
+ F32 mNormalRepeatY;
+ F32 mNormalRotation;
+
+ LLUUID mSpecularID;
+ F32 mSpecularOffsetX;
+ F32 mSpecularOffsetY;
+ F32 mSpecularRepeatX;
+ F32 mSpecularRepeatY;
+ F32 mSpecularRotation;
+
+ LLColor4U mSpecularLightColor;
+ U8 mSpecularLightExponent;
+ U8 mEnvironmentIntensity;
+ U8 mDiffuseAlphaMode;
+ U8 mAlphaMaskCutoff;
+};
+
+typedef LLPointer<LLMaterial> LLMaterialPtr;
+
+#endif // LL_LLMATERIAL_H
+
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp
new file mode 100644
index 0000000000..820f62c43c
--- /dev/null
+++ b/indra/llprimitive/llmaterialid.cpp
@@ -0,0 +1,183 @@
+/**
+* @file llmaterialid.cpp
+* @brief Implementation of llmaterialid
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llmaterialid.h"
+
+#include <string>
+
+#include "llformat.h"
+
+const LLMaterialID LLMaterialID::null;
+
+LLMaterialID::LLMaterialID()
+{
+ clear();
+}
+
+LLMaterialID::LLMaterialID(const LLSD& pMaterialID)
+{
+ llassert(pMaterialID.isBinary());
+ parseFromBinary(pMaterialID.asBinary());
+}
+
+LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID)
+{
+ parseFromBinary(pMaterialID);
+}
+
+LLMaterialID::LLMaterialID(const void* pMemory)
+{
+ set(pMemory);
+}
+
+LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID)
+{
+ copyFromOtherMaterialID(pOtherMaterialID);
+}
+
+LLMaterialID::~LLMaterialID()
+{
+}
+
+bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) == 0);
+}
+
+bool LLMaterialID::operator != (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) != 0);
+}
+
+bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) < 0);
+}
+
+bool LLMaterialID::operator <= (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) <= 0);
+}
+
+bool LLMaterialID::operator > (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) > 0);
+}
+
+bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) >= 0);
+}
+
+LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID)
+{
+ copyFromOtherMaterialID(pOtherMaterialID);
+ return (*this);
+}
+
+bool LLMaterialID::isNull() const
+{
+ return (compareToOtherMaterialID(LLMaterialID::null) == 0);
+}
+
+const U8* LLMaterialID::get() const
+{
+ return mID;
+}
+
+void LLMaterialID::set(const void* pMemory)
+{
+ llassert(pMemory != NULL);
+
+ // assumes that the required size of memory is available
+ memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+void LLMaterialID::clear()
+{
+ memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+LLSD LLMaterialID::asLLSD() const
+{
+ LLSD::Binary materialIDBinary;
+
+ materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8));
+ memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8));
+
+ LLSD materialID = materialIDBinary;
+ return materialID;
+}
+
+std::string LLMaterialID::asString() const
+{
+ std::string materialIDString;
+ for (unsigned int i = 0U; i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32)); ++i)
+ {
+ if (i != 0U)
+ {
+ materialIDString += "-";
+ }
+ const U32 *value = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
+ materialIDString += llformat("%08x", *value);
+ }
+ return materialIDString;
+}
+
+std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
+{
+ s << material_id.asString();
+ return s;
+}
+
+
+void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID)
+{
+ llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8)));
+ memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID)
+{
+ memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const
+{
+ int retVal = 0;
+
+ for (unsigned int i = 0U; (retVal == 0) && (i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32))); ++i)
+ {
+ const U32 *thisValue = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
+ const U32 *otherValue = reinterpret_cast<const U32*>(&pOtherMaterialID.get()[i * sizeof(U32)]);
+ retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0));
+ }
+
+ return retVal;
+}
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h
new file mode 100644
index 0000000000..0a95204085
--- /dev/null
+++ b/indra/llprimitive/llmaterialid.h
@@ -0,0 +1,76 @@
+/**
+* @file llmaterialid.h
+* @brief Header file for llmaterialid
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLMATERIALID_H
+#define LL_LLMATERIALID_H
+
+#define MATERIAL_ID_SIZE 16
+
+#include <string>
+
+class LLMaterialID
+{
+public:
+ LLMaterialID();
+ LLMaterialID(const LLSD& pMaterialID);
+ LLMaterialID(const LLSD::Binary& pMaterialID);
+ LLMaterialID(const void* pMemory);
+ LLMaterialID(const LLMaterialID& pOtherMaterialID);
+ ~LLMaterialID();
+
+ bool operator == (const LLMaterialID& pOtherMaterialID) const;
+ bool operator != (const LLMaterialID& pOtherMaterialID) const;
+
+ bool operator < (const LLMaterialID& pOtherMaterialID) const;
+ bool operator <= (const LLMaterialID& pOtherMaterialID) const;
+ bool operator > (const LLMaterialID& pOtherMaterialID) const;
+ bool operator >= (const LLMaterialID& pOtherMaterialID) const;
+
+ LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID);
+
+ bool isNull() const;
+
+ const U8* get() const;
+ void set(const void* pMemory);
+ void clear();
+
+ LLSD asLLSD() const;
+ std::string asString() const;
+
+ friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id);
+
+ static const LLMaterialID null;
+
+private:
+ void parseFromBinary(const LLSD::Binary& pMaterialID);
+ void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
+ int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const;
+
+ U8 mID[MATERIAL_ID_SIZE];
+} ;
+
+#endif // LL_LLMATERIALID_H
+
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index c340fc2d35..2fa77177f5 100755
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -39,6 +39,7 @@
#include "llsdutil_math.h"
#include "llprimtexturelist.h"
#include "imageids.h"
+#include "llmaterialid.h"
/**
* exported constants
@@ -314,6 +315,15 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r)
return mTextureList.setRotation(index, r);
}
+S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID)
+{
+ return mTextureList.setMaterialID(index, pMaterialID);
+}
+
+S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
+{
+ return mTextureList.setMaterialParams(index, pMaterialParams);
+}
//===============================================================
S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
@@ -364,6 +374,23 @@ S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)
return mTextureList.setGlow(index, glow);
}
+void LLPrimitive::setAllTESelected(bool sel)
+{
+ for (int i = 0, cnt = getNumTEs(); i < cnt; i++)
+ {
+ setTESelected(i, sel);
+ }
+}
+
+void LLPrimitive::setTESelected(const U8 te, bool sel)
+{
+ LLTextureEntry* tep = getTE(te);
+ if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) )
+ {
+ LLMaterialID material_id = tep->getMaterialID();
+ setTEMaterialID(te, material_id);
+ }
+}
LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
{
@@ -1044,7 +1071,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat
while ((cur_ptr < buffer_end) && (*cur_ptr != 0))
{
-// llinfos << "TE exception" << llendl;
+ LL_DEBUGS("TEFieldDecode") << "TE exception" << LL_ENDL;
i = 0;
while (*cur_ptr & 0x80)
{
@@ -1059,14 +1086,16 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat
if (i & 0x01)
{
htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size);
-// char foo[64];
-// sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
-// llinfos << "Assigning " << foo << " to face " << j << llendl;
+ LL_DEBUGS("TEFieldDecode") << "Assigning " ;
+ char foo[64];
+ sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
+ LL_CONT << foo << " to face " << j << LL_ENDL;
}
i = i >> 1;
}
cur_ptr += data_size;
}
+ llassert(cur_ptr <= buffer_end); // buffer underrun
return (S32)(cur_ptr - start_loc);
}
@@ -1088,6 +1117,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1125,6 +1155,9 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
bump[face_index] = te->getBumpShinyFullbright();
media_flags[face_index] = te->getMediaTexGen();
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
+
+ // Directly sending material_ids is not safe!
+ memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
}
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
@@ -1146,6 +1179,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
}
mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
@@ -1167,6 +1202,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1204,6 +1240,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
bump[face_index] = te->getBumpShinyFullbright();
media_flags[face_index] = te->getMediaTexGen();
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
+
+ // Directly sending material_ids is not safe!
+ memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
}
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
@@ -1225,6 +1264,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
}
dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
@@ -1234,6 +1275,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)
{
S32 retval = 0;
+ // temp buffer for material ID processing
+ // data will end up in tec.material_id[]
+ U8 material_data[LLTEContents::MAX_TES*16];
if (block_num < 0)
{
@@ -1282,14 +1326,29 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8);
+ if (cur_ptr < tec.packed_buffer + tec.size)
+ {
+ cur_ptr++;
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)material_data, 16, tec.face_count, MVT_LLUUID);
+ }
+ else
+ {
+ memset(material_data, 0, sizeof(material_data));
+ }
+
+ for (U32 i = 0; i < tec.face_count; i++)
+ {
+ tec.material_ids[i].set(&material_data[i * 16]);
+ }
+
retval = 1;
return retval;
-}
-
+ }
+
S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
{
S32 retval = 0;
-
+
LLColor4 color;
LLColor4U coloru;
for (U32 i = 0; i < tec.face_count; i++)
@@ -1302,6 +1361,9 @@ S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
retval |= setTEMediaTexGen(i, tec.media_flags[i]);
retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
+
+ retval |= setTEMaterialID(i, tec.material_ids[i]);
+
coloru = LLColor4U(tec.colors + 4*i);
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
@@ -1336,6 +1398,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
// Avoid construction of 32 UUIDs per call
static LLUUID image_ids[MAX_TES];
+ static LLMaterialID material_ids[MAX_TES];
U8 image_data[MAX_TES*16];
U8 colors[MAX_TES*4];
@@ -1347,6 +1410,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1389,10 +1453,20 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
+ if (cur_ptr < packed_buffer + size)
+ {
+ cur_ptr++;
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID);
+ }
+ else
+ {
+ memset(material_data, 0, sizeof(material_data));
+ }
for (i = 0; i < face_count; i++)
{
memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */
+ material_ids[i].set(&material_data[i * 16]);
}
LLColor4 color;
@@ -1406,6 +1480,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
retval |= setTEBumpShinyFullbright(i, bump[i]);
retval |= setTEMediaTexGen(i, media_flags[i]);
retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
+ retval |= setTEMaterialID(i, material_ids[i]);
coloru = LLColor4U(colors + 4*i);
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 6a8b59c81c..47a21beaaf 100755
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -42,6 +42,7 @@ class LLMessageSystem;
class LLVolumeParams;
class LLColor4;
class LLColor3;
+class LLMaterialID;
class LLTextureEntry;
class LLDataPacker;
class LLVolumeMgr;
@@ -309,7 +310,8 @@ struct LLTEContents
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
-
+ LLMaterialID material_ids[MAX_TES];
+
static const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -359,6 +361,7 @@ public:
LLTextureEntry* getTE(const U8 te_num) const;
virtual void setNumTEs(const U8 num_tes);
+ virtual void setAllTESelected(bool sel);
virtual void setAllTETextures(const LLUUID &tex_id);
virtual void setTE(const U8 index, const LLTextureEntry& te);
virtual S32 setTEColor(const U8 te, const LLColor4 &color);
@@ -381,7 +384,10 @@ public:
virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
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 BOOL setMaterial(const U8 material); // returns TRUE if material changed
+ virtual void setTESelected(const U8 te, bool sel);
void copyTEs(const LLPrimitive *primitive);
S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp
index 7ef87ed382..537e7a6695 100755
--- a/indra/llprimitive/llprimtexturelist.cpp
+++ b/indra/llprimitive/llprimtexturelist.cpp
@@ -27,6 +27,7 @@
#include "linden_common.h"
#include "llprimtexturelist.h"
+#include "llmaterialid.h"
#include "lltextureentry.h"
// static
@@ -358,6 +359,24 @@ S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow)
return TEM_CHANGE_NONE;
}
+S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID)
+{
+ if (index < mEntryList.size())
+ {
+ return mEntryList[index]->setMaterialID(pMaterialID);
+ }
+ return TEM_CHANGE_NONE;
+}
+
+S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
+{
+ if (index < mEntryList.size())
+ {
+ return mEntryList[index]->setMaterialParams(pMaterialParams);
+ }
+ return TEM_CHANGE_NONE;
+}
+
S32 LLPrimTextureList::size() const
{
return mEntryList.size();
diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h
index 3cfa52f1d5..d7fabbbb79 100755
--- a/indra/llprimitive/llprimtexturelist.h
+++ b/indra/llprimitive/llprimtexturelist.h
@@ -31,9 +31,11 @@
#include "lluuid.h"
#include "v3color.h"
#include "v4color.h"
+#include "llmaterial.h"
class LLTextureEntry;
+class LLMaterialID;
// this is a list of LLTextureEntry*'s because in practice the list's elements
// are of some derived class: LLFooTextureEntry
@@ -102,6 +104,8 @@ public:
S32 setFullbright(const U8 index, const U8 t);
S32 setMediaFlags(const U8 index, const U8 media_flags);
S32 setGlow(const U8 index, const F32 glow);
+ S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID);
+ S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
S32 size() const;
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 34eff17519..597f078490 100755
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -29,6 +29,7 @@
#include "lluuid.h"
#include "llmediaentry.h"
#include "lltextureentry.h"
+#include "llmaterialid.h"
#include "llsdutil_math.h"
#include "v4color.h"
@@ -60,18 +61,24 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()
//===============================================================
LLTextureEntry::LLTextureEntry()
: mMediaEntry(NULL)
+ , mSelected(false)
+ , mMaterialUpdatePending(false)
{
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
: mMediaEntry(NULL)
+ , mSelected(false)
+ , mMaterialUpdatePending(false)
{
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
: mMediaEntry(NULL)
+ , mSelected(false)
+ , mMaterialUpdatePending(false)
{
mID = rhs.mID;
mScaleS = rhs.mScaleS;
@@ -83,6 +90,8 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
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);
@@ -103,6 +112,8 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ mMaterialID = rhs.mMaterialID;
+ mMaterial = rhs.mMaterial;
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
@@ -130,6 +141,7 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
mBump = bump;
mMediaFlags = 0x0;
mGlow = 0;
+ mMaterialID.clear();
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
if (mMediaEntry != NULL) {
@@ -159,6 +171,7 @@ bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
if (mBump != rhs.mBump) return (true);
if (mMediaFlags != rhs.mMediaFlags) return (true);
if (mGlow != rhs.mGlow) return (true);
+ if (mMaterialID != rhs.mMaterialID) return (true);
return(false);
}
@@ -174,6 +187,7 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const
if (mBump != rhs.mBump) return (false);
if (mMediaFlags != rhs.mMediaFlags) return false;
if (mGlow != rhs.mGlow) return false;
+ if (mMaterialID != rhs.mMaterialID) return (false);
return(true);
}
@@ -523,6 +537,34 @@ S32 LLTextureEntry::setGlow(F32 glow)
return TEM_CHANGE_NONE;
}
+S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
+{
+ if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) )
+ {
+ if (mSelected)
+ {
+ mMaterialUpdatePending = true;
+ mMaterialID = pMaterialID;
+ return TEM_CHANGE_NONE;
+ }
+
+ mMaterialUpdatePending = false;
+ mMaterialID = pMaterialID;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
+}
+
+S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
+{
+ if (mSelected)
+ {
+ mMaterialUpdatePending = true;
+ }
+ mMaterial = pMaterialParams;
+ return TEM_CHANGE_TEXTURE;
+}
+
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
{
mMediaFlags |= MF_HAS_MEDIA;
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index 437b85e03f..19edcaa27d 100755
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -30,6 +30,8 @@
#include "lluuid.h"
#include "v4color.h"
#include "llsd.h"
+#include "llmaterialid.h"
+#include "llmaterial.h"
// These bits are used while unpacking TEM messages to tell which aspects of
// the texture entry changed.
@@ -98,6 +100,10 @@ public:
void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump);
+ bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; }
+ bool isSelected() const { return mSelected; }
+ bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; }
+
// These return a TEM_ flag from above to indicate if something changed.
S32 setID (const LLUUID &tex_id);
S32 setColor(const LLColor4 &color);
@@ -121,11 +127,19 @@ public:
S32 setTexGen(U8 texGen);
S32 setMediaTexGen(U8 media);
S32 setGlow(F32 glow);
+ S32 setMaterialID(const LLMaterialID& pMaterialID);
+ S32 setMaterialParams(const LLMaterialPtr pMaterialParams);
virtual const LLUUID &getID() const { return mID; }
const LLColor4 &getColor() const { return mColor; }
void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; }
+ F32 getScaleS() const { return mScaleS; }
+ F32 getScaleT() const { return mScaleT; }
+
void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; }
+ F32 getOffsetS() const { return mOffsetS; }
+ F32 getOffsetT() const { return mOffsetT; }
+
F32 getRotation() const { return mRotation; }
void getRotation(F32 *theta) const { *theta = mRotation; }
@@ -136,9 +150,11 @@ public:
U8 getBumpShinyFullbright() const { return mBump; }
U8 getMediaFlags() const { return mMediaFlags & TEM_MEDIA_MASK; }
- U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
+ LLTextureEntry::e_texgen getTexGen() const { return LLTextureEntry::e_texgen(mMediaFlags & TEM_TEX_GEN_MASK); }
U8 getMediaTexGen() const { return mMediaFlags; }
F32 getGlow() const { return mGlow; }
+ const LLMaterialID& getMaterialID() const { return mMaterialID; };
+ const LLMaterialPtr getMaterialParams() const { return mMaterial; };
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
@@ -188,11 +204,15 @@ public:
static const char* TEXTURE_MEDIA_DATA_KEY;
protected:
+ bool mSelected;
LLUUID mID; // Texture GUID
LLColor4 mColor;
U8 mBump; // Bump map, shiny, and fullbright
U8 mMediaFlags; // replace with web page, movie, etc.
F32 mGlow;
+ bool mMaterialUpdatePending;
+ LLMaterialID mMaterialID;
+ LLMaterialPtr mMaterial;
// 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/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 669b70aa43..dba12d048e 100755
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -92,7 +92,7 @@ if (BUILD_HEADLESS)
set_property(TARGET llrenderheadless
PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
- )
+ )
target_link_libraries(llrenderheadless
${LLCOMMON_LIBRARIES}
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 1b1799aaa2..2f7b2f9a1c 100755
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -86,7 +86,7 @@ void APIENTRY gl_debug_callback(GLenum source,
}
else
{
- llwarns << "----- GL WARNING -------" << llendl;
+ llwarns << "----- GL WARNING -------" << llendl;
}
llwarns << "Type: " << std::hex << type << llendl;
llwarns << "ID: " << std::hex << id << llendl;
@@ -216,6 +216,11 @@ 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;
@@ -421,6 +426,7 @@ LLGLManager::LLGLManager() :
mHasFragmentShader(FALSE),
mNumTextureImageUnits(0),
mHasOcclusionQuery(FALSE),
+ mHasTimerQuery(FALSE),
mHasOcclusionQuery2(FALSE),
mHasPointParameters(FALSE),
mHasDrawBuffers(FALSE),
@@ -445,7 +451,9 @@ LLGLManager::LLGLManager() :
mIsGFFX(FALSE),
mATIOffsetVerticalLines(FALSE),
mATIOldDriver(FALSE),
-
+#if LL_DARWIN
+ mIsMobileGF(FALSE),
+#endif
mHasRequirements(TRUE),
mHasSeparateSpecularColor(FALSE),
@@ -638,6 +646,13 @@ bool LLGLManager::initGL()
{
mIsGF3 = TRUE;
}
+#if LL_DARWIN
+ else if ((mGLRenderer.find("9400M") != std::string::npos)
+ || (mGLRenderer.find("9600M") != std::string::npos))
+ {
+ mIsMobileGF = TRUE;
+ }
+#endif
}
else if (mGLVendor.find("INTEL") != std::string::npos
@@ -746,12 +761,13 @@ bool LLGLManager::initGL()
{ //using multisample textures on ATI results in black screen for some reason
mHasTextureMultisample = FALSE;
}
-#endif
+
if (mIsIntel && mGLVersion <= 3.f)
{ //never try to use framebuffer objects on older intel drivers (crashy)
mHasFramebufferObject = FALSE;
}
+#endif
if (mHasFramebufferObject)
{
@@ -948,13 +964,15 @@ void LLGLManager::initExtensions()
mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
+ 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);
- mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
+ //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);
@@ -964,6 +982,15 @@ void LLGLManager::initExtensions()
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
mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
@@ -1254,6 +1281,13 @@ void LLGLManager::initExtensions()
glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
}
+ if (mHasTimerQuery)
+ {
+ llinfos << "initExtensions() TimerQuery-related procs..." << llendl;
+ 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)
{
llinfos << "initExtensions() PointParameters-related procs..." << llendl;
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index d70e764769..60597fd090 100755
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -98,6 +98,7 @@ public:
BOOL mHasFragmentShader;
S32 mNumTextureImageUnits;
BOOL mHasOcclusionQuery;
+ BOOL mHasTimerQuery;
BOOL mHasOcclusionQuery2;
BOOL mHasPointParameters;
BOOL mHasDrawBuffers;
@@ -115,6 +116,8 @@ public:
BOOL mHasARBEnvCombine;
BOOL mHasCubeMap;
BOOL mHasDebugOutput;
+ BOOL mHassRGBTexture;
+ BOOL mHassRGBFramebuffer;
// Vendor-specific extensions
BOOL mIsATI;
@@ -126,6 +129,11 @@ public:
BOOL mATIOffsetVerticalLines;
BOOL mATIOldDriver;
+#if LL_DARWIN
+ // Needed to distinguish problem cards on older Macs that break with Materials
+ BOOL mIsMobileGF;
+#endif
+
// Whether this version of GL is good enough for SL to use
BOOL mHasRequirements;
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 509de51f4d..dace572953 100755
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -116,6 +116,11 @@ 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;
@@ -378,6 +383,11 @@ 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;
@@ -619,6 +629,12 @@ 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;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 7cbf39096e..ac16e30796 100755
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -53,6 +53,12 @@ GLhandleARB LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
bool LLGLSLShader::sNoFixedFunction = false;
+bool LLGLSLShader::sProfileEnabled = false;
+std::set<LLGLSLShader*> LLGLSLShader::sInstances;
+U64 LLGLSLShader::sTotalTimeElapsed = 0;
+U32 LLGLSLShader::sTotalTrianglesDrawn = 0;
+U64 LLGLSLShader::sTotalSamplesDrawn = 0;
+U32 LLGLSLShader::sTotalDrawCalls = 0;
//UI shader -- declared here so llui_libtest will link properly
LLGLSLShader gUIProgram;
@@ -87,19 +93,240 @@ LLShaderFeatures::LLShaderFeatures()
//===============================
// LLGLSL Shader implementation
//===============================
+
+//static
+void LLGLSLShader::initProfile()
+{
+ sProfileEnabled = true;
+ sTotalTimeElapsed = 0;
+ sTotalTrianglesDrawn = 0;
+ sTotalSamplesDrawn = 0;
+ sTotalDrawCalls = 0;
+
+ for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
+ {
+ (*iter)->clearStats();
+ }
+}
+
+
+struct LLGLSLShaderCompareTimeElapsed
+{
+ bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
+ {
+ return lhs->mTimeElapsed < rhs->mTimeElapsed;
+ }
+};
+
+//static
+void LLGLSLShader::finishProfile()
+{
+ sProfileEnabled = false;
+
+ std::vector<LLGLSLShader*> sorted;
+
+ for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
+ {
+ sorted.push_back(*iter);
+ }
+
+ std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed());
+
+ for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
+ {
+ (*iter)->dumpStats();
+ }
+
+ llinfos << "-----------------------------------" << llendl;
+ llinfos << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << llendl;
+ llinfos << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << llendl;
+ llinfos << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << llendl;
+}
+
+void LLGLSLShader::clearStats()
+{
+ mTrianglesDrawn = 0;
+ mTimeElapsed = 0;
+ mSamplesDrawn = 0;
+ mDrawCalls = 0;
+ mTextureStateFetched = false;
+ mTextureMagFilter.clear();
+ mTextureMinFilter.clear();
+}
+
+void LLGLSLShader::dumpStats()
+{
+ if (mDrawCalls > 0)
+ {
+ llinfos << "=============================================" << llendl;
+ llinfos << mName << llendl;
+ for (U32 i = 0; i < mShaderFiles.size(); ++i)
+ {
+ llinfos << mShaderFiles[i].first << llendl;
+ }
+ for (U32 i = 0; i < mTexture.size(); ++i)
+ {
+ GLint idx = mTexture[i];
+
+ if (idx >= 0)
+ {
+ GLint uniform_idx = getUniformLocation(i);
+ llinfos << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << llendl;
+ }
+ }
+ llinfos << "=============================================" << llendl;
+
+ F32 ms = mTimeElapsed/1000000.f;
+ F32 seconds = ms/1000.f;
+
+ F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f;
+ F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0);
+ tris_sec /= seconds;
+
+ F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f;
+ F32 samples_sec = (F32) mSamplesDrawn/1000000000.0;
+ samples_sec /= seconds;
+
+ F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f;
+ U32 avg_batch = mTrianglesDrawn/mDrawCalls;
+
+ llinfos << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << llendl;
+ llinfos << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << llendl;
+ llinfos << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << llendl;
+ llinfos << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << llendl;
+ }
+}
+
+//static
+void LLGLSLShader::startProfile()
+{
+ if (sProfileEnabled && sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->placeProfileQuery();
+ }
+
+}
+
+//static
+void LLGLSLShader::stopProfile(U32 count, U32 mode)
+{
+ if (sProfileEnabled)
+ {
+ sCurBoundShaderPtr->readProfileQuery(count, mode);
+ }
+}
+
+void LLGLSLShader::placeProfileQuery()
+{
+#if !LL_DARWIN
+ if (mTimerQuery == 0)
+ {
+ glGenQueriesARB(1, &mTimerQuery);
+ }
+
+ if (!mTextureStateFetched)
+ {
+ mTextureStateFetched = true;
+ mTextureMagFilter.resize(mTexture.size());
+ mTextureMinFilter.resize(mTexture.size());
+
+ U32 cur_active = gGL.getCurrentTexUnitIndex();
+
+ for (U32 i = 0; i < mTexture.size(); ++i)
+ {
+ GLint idx = mTexture[i];
+
+ if (idx >= 0)
+ {
+ gGL.getTexUnit(idx)->activate();
+
+ U32 mag = 0xFFFFFFFF;
+ U32 min = 0xFFFFFFFF;
+
+ U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
+
+ glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
+ glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
+
+ mTextureMagFilter[i] = mag;
+ mTextureMinFilter[i] = min;
+ }
+ }
+
+ gGL.getTexUnit(cur_active)->activate();
+ }
+
+
+ glBeginQueryARB(GL_SAMPLES_PASSED, 1);
+ glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
+#endif
+}
+
+void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
+{
+#if !LL_DARWIN
+ glEndQueryARB(GL_TIME_ELAPSED);
+ glEndQueryARB(GL_SAMPLES_PASSED);
+
+ U64 time_elapsed = 0;
+ glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+
+ U64 samples_passed = 0;
+ glGetQueryObjectui64v(1, GL_QUERY_RESULT, &samples_passed);
+
+ sTotalTimeElapsed += time_elapsed;
+ mTimeElapsed += time_elapsed;
+
+ sTotalSamplesDrawn += samples_passed;
+ mSamplesDrawn += samples_passed;
+
+ U32 tri_count = 0;
+ switch (mode)
+ {
+ case LLRender::TRIANGLES: tri_count = count/3; break;
+ case LLRender::TRIANGLE_FAN: tri_count = count-2; break;
+ case LLRender::TRIANGLE_STRIP: tri_count = count-2; break;
+ default: tri_count = count; break; //points lines etc just use primitive count
+ }
+
+ mTrianglesDrawn += tri_count;
+ sTotalTrianglesDrawn += tri_count;
+
+ sTotalDrawCalls++;
+ mDrawCalls++;
+#endif
+}
+
+
+
LLGLSLShader::LLGLSLShader()
- : mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
+ : mProgramObject(0),
+ mAttributeMask(0),
+ mTotalUniformSize(0),
+ mActiveTextureChannels(0),
+ mShaderLevel(0),
+ mShaderGroup(SG_DEFAULT),
+ mUniformsDirty(FALSE),
+ mTimerQuery(0)
{
+
+}
+LLGLSLShader::~LLGLSLShader()
+{
+
}
void LLGLSLShader::unload()
{
+ sInstances.erase(this);
+
stop_glerror();
mAttribute.clear();
mTexture.clear();
mUniform.clear();
mShaderFiles.clear();
+ mDefines.clear();
if (mProgramObject)
{
@@ -133,6 +360,8 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
U32 varying_count,
const char** varyings)
{
+ sInstances.insert(this);
+
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
{
@@ -150,7 +379,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
{
- GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
+ GLhandleARB 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 > 0)
{
@@ -285,6 +514,8 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
if (res)
{ //read back channel locations
+ mAttributeMask = 0;
+
//read back reserved channels first
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
@@ -293,6 +524,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
if (index != -1)
{
mAttribute[i] = index;
+ mAttributeMask |= 1 << i;
LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
}
}
@@ -325,11 +557,56 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
GLenum type;
GLsizei length;
- GLint size;
+ GLint size = -1;
char name[1024]; /* Flawfinder: ignore */
name[0] = 0;
+
glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
+#if !LL_DARWIN
+ if (size > 0)
+ {
+ switch(type)
+ {
+ case GL_FLOAT_VEC2: size *= 2; break;
+ case GL_FLOAT_VEC3: size *= 3; break;
+ case GL_FLOAT_VEC4: size *= 4; break;
+ case GL_DOUBLE: size *= 2; break;
+ case GL_DOUBLE_VEC2: size *= 2; break;
+ case GL_DOUBLE_VEC3: size *= 6; break;
+ case GL_DOUBLE_VEC4: size *= 8; break;
+ case GL_INT_VEC2: size *= 2; break;
+ case GL_INT_VEC3: size *= 3; break;
+ case GL_INT_VEC4: size *= 4; break;
+ case GL_UNSIGNED_INT_VEC2: size *= 2; break;
+ case GL_UNSIGNED_INT_VEC3: size *= 3; break;
+ case GL_UNSIGNED_INT_VEC4: size *= 4; break;
+ case GL_BOOL_VEC2: size *= 2; break;
+ case GL_BOOL_VEC3: size *= 3; break;
+ case GL_BOOL_VEC4: size *= 4; break;
+ case GL_FLOAT_MAT2: size *= 4; break;
+ case GL_FLOAT_MAT3: size *= 9; break;
+ case GL_FLOAT_MAT4: size *= 16; break;
+ case GL_FLOAT_MAT2x3: size *= 6; break;
+ case GL_FLOAT_MAT2x4: size *= 8; break;
+ case GL_FLOAT_MAT3x2: size *= 6; break;
+ case GL_FLOAT_MAT3x4: size *= 12; break;
+ case GL_FLOAT_MAT4x2: size *= 8; break;
+ case GL_FLOAT_MAT4x3: size *= 12; break;
+ case GL_DOUBLE_MAT2: size *= 8; break;
+ case GL_DOUBLE_MAT3: size *= 18; break;
+ case GL_DOUBLE_MAT4: size *= 32; break;
+ case GL_DOUBLE_MAT2x3: size *= 12; break;
+ case GL_DOUBLE_MAT2x4: size *= 16; break;
+ case GL_DOUBLE_MAT3x2: size *= 12; break;
+ case GL_DOUBLE_MAT3x4: size *= 24; break;
+ case GL_DOUBLE_MAT4x2: size *= 16; break;
+ case GL_DOUBLE_MAT4x3: size *= 24; break;
+ }
+ mTotalUniformSize += size;
+ }
+#endif
+
S32 location = glGetUniformLocationARB(mProgramObject, name);
if (location != -1)
{
@@ -342,6 +619,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
}
mUniformMap[name] = location;
+ mUniformNameMap[location] = name;
LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
//find the index of this uniform
@@ -372,11 +650,21 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
}
}
}
- }
+}
+
+void LLGLSLShader::addPermutation(std::string name, std::string value)
+{
+ mDefines[name] = value;
+}
+
+void LLGLSLShader::removePermutation(std::string name)
+{
+ mDefines[name].erase();
+}
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
{
- if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB ||
+ if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
type == GL_SAMPLER_2D_MULTISAMPLE)
{ //this here is a texture
glUniform1iARB(location, mActiveTextureChannels);
@@ -390,9 +678,11 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
{
BOOL res = TRUE;
+ mTotalUniformSize = 0;
mActiveTextureChannels = 0;
mUniform.clear();
mUniformMap.clear();
+ mUniformNameMap.clear();
mTexture.clear();
mValue.clear();
//initialize arrays
@@ -413,6 +703,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
unbind();
+ LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << llendl;
return res;
}
@@ -471,6 +762,58 @@ void LLGLSLShader::bindNoShader(void)
}
}
+S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+{
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return bindTexture(channel, texture, mode);
+}
+
+S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+{
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->bind(texture, mode);
+ }
+
+ return uniform;
+}
+
+S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
+{
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return unbindTexture(channel);
+}
+
+S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
+{
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->unbind(mode);
+ }
+
+ return uniform;
+}
+
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
@@ -857,6 +1200,23 @@ void LLGLSLShader::uniform1i(const string& uniform, GLint v)
}
}
+void LLGLSLShader::uniform2i(const string& uniform, GLint i, GLint j)
+{
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ LLVector4 vec(i,j,0.f,0.f);
+ if (iter == mValue.end() || shouldChange(iter->second,vec))
+ {
+ glUniform2iARB(location, i, j);
+ mValue[location] = vec;
+ }
+ }
+}
+
+
void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
{
GLint location = getUniformLocation(uniform);
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index cf21101e35..eabdb9fc92 100755
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -67,14 +67,29 @@ public:
SG_WATER
};
+ static std::set<LLGLSLShader*> sInstances;
+ static bool sProfileEnabled;
+
LLGLSLShader();
+ ~LLGLSLShader();
static GLhandleARB sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
static bool sNoFixedFunction;
+ static void initProfile();
+ static void finishProfile();
+
+ static void startProfile();
+ static void stopProfile(U32 count, U32 mode);
+
void unload();
+ void clearStats();
+ void dumpStats();
+ void placeProfileQuery();
+ void readProfileQuery(U32 count, U32 mode);
+
BOOL createShader(std::vector<std::string> * attributes,
std::vector<std::string> * uniforms,
U32 varying_count = 0,
@@ -96,6 +111,7 @@ public:
void uniform3fv(U32 index, U32 count, const GLfloat* v);
void uniform4fv(U32 index, U32 count, const GLfloat* v);
void uniform1i(const std::string& uniform, GLint i);
+ void uniform2i(const std::string& uniform, GLint i, GLint j);
void uniform1f(const std::string& uniform, GLfloat v);
void uniform2f(const std::string& uniform, GLfloat x, GLfloat y);
void uniform3f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z);
@@ -123,12 +139,22 @@ public:
GLint getAttribLocation(U32 attrib);
GLint mapUniformTextureChannel(GLint location, GLenum type);
+ void addPermutation(std::string name, std::string value);
+ void removePermutation(std::string name);
+
//enable/disable texture channel for specified uniform
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
//returns channel texture is enabled in from [0-MAX)
S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
- S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+
+ // bindTexture returns the texture unit we've bound the texture to.
+ // You can reuse the return value to unbind a texture when required.
+ S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
BOOL link(BOOL suppress_errors = FALSE);
void bind();
@@ -142,10 +168,13 @@ public:
GLhandleARB mProgramObject;
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
+ U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
std::map<std::string, GLint> mUniformMap; //lookup map of uniform name to uniform location
+ std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
std::vector<GLint> mTexture;
+ S32 mTotalUniformSize;
S32 mActiveTextureChannels;
S32 mShaderLevel;
S32 mShaderGroup;
@@ -153,6 +182,23 @@ public:
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
+ boost::unordered_map<std::string, std::string> mDefines;
+
+ //statistcis for profiling shader performance
+ U32 mTimerQuery;
+ U64 mTimeElapsed;
+ static U64 sTotalTimeElapsed;
+ U32 mTrianglesDrawn;
+ static U32 sTotalTrianglesDrawn;
+ U64 mSamplesDrawn;
+ static U64 sTotalSamplesDrawn;
+ U32 mDrawCalls;
+ static U32 sTotalDrawCalls;
+
+ bool mTextureStateFetched;
+ std::vector<U32> mTextureMagFilter;
+ std::vector<U32> mTextureMinFilter;
+
};
//UI shader (declared here so llui_libtest will link properly)
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 5c171d372c..38764eba23 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -748,12 +748,16 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
S32 height = getHeight(mCurrentDiscardLevel);
S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;
S32 w = width, h = height;
+
+
+ const U8* new_data = 0;
+ (void)new_data;
+
const U8* prev_mip_data = 0;
const U8* cur_mip_data = 0;
#ifdef SHOW_ASSERT
S32 cur_mip_size = 0;
#endif
-
mMipLevels = nummips;
for (int m=0; m<nummips; m++)
@@ -773,14 +777,22 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
llassert(cur_mip_size == bytes*4);
#endif
U8* new_data = new U8[bytes];
+
+#ifdef SHOW_ASSERT
+ llassert(prev_mip_data);
+ llassert(cur_mip_size == bytes*4);
llassert_always(new_data);
+#endif
+
LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
cur_mip_data = new_data;
#ifdef SHOW_ASSERT
cur_mip_size = bytes;
#endif
+
}
llassert(w > 0 && h > 0 && cur_mip_data);
+ (void)cur_mip_data;
{
// LLFastTimer t1(FTM_TEMP4);
if(mFormatSwapBytes)
@@ -1119,30 +1131,30 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip
default:
{
if (type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
- { //unknown internal format or unknown number of mip levels, not safe to reuse
- glDeleteTextures(numTextures, textures);
- }
- else
- {
- for (S32 i = 0; i < numTextures; ++i)
- { //remove texture from VRAM by setting its size to zero
+ { //unknown internal format or unknown number of mip levels, not safe to reuse
+ glDeleteTextures(numTextures, textures);
+ }
+ else
+ {
+ for (S32 i = 0; i < numTextures; ++i)
+ { //remove texture from VRAM by setting its size to zero
- for (S32 j = 0; j <= mip_levels; j++)
- {
- gGL.getTexUnit(0)->bindManual(type, textures[i]);
+ for (S32 j = 0; j <= mip_levels; j++)
+ {
+ gGL.getTexUnit(0)->bindManual(type, textures[i]);
U32 internal_type = LLTexUnit::getInternalType(type);
glTexImage2D(internal_type, j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
stop_glerror();
- }
+ }
- llassert(std::find(sDeadTextureList[type][format].begin(),
- sDeadTextureList[type][format].end(), textures[i]) ==
- sDeadTextureList[type][format].end());
+ llassert(std::find(sDeadTextureList[type][format].begin(),
+ sDeadTextureList[type][format].end(), textures[i]) ==
+ sDeadTextureList[type][format].end());
- sDeadTextureList[type][format].push_back(textures[i]);
- }
- }
- }
+ sDeadTextureList[type][format].push_back(textures[i]);
+ }
+ }
+ }
break;
}
}
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 78a310e525..98222939e7 100755
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -262,6 +262,14 @@ class LLRender
friend class LLTexUnit;
public:
+ enum eTexIndex
+ {
+ DIFFUSE_MAP = 0,
+ NORMAL_MAP,
+ SPECULAR_MAP,
+ NUM_TEXTURE_CHANNELS,
+ };
+
typedef enum {
TRIANGLES = 0,
TRIANGLE_STRIP,
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 5fb4fc8e52..6e22712b94 100755
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -53,11 +53,19 @@ void check_framebuffer_status()
bool LLRenderTarget::sUseFBO = false;
U32 LLRenderTarget::sCurFBO = 0;
+
+extern S32 gGLViewport[4];
+
+U32 LLRenderTarget::sCurResX = 0;
+U32 LLRenderTarget::sCurResY = 0;
+
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
mFBO(0),
mPreviousFBO(0),
+ mPreviousResX(0),
+ mPreviousResY(0),
mDepth(0),
mStencil(0),
mUseDepth(false),
@@ -390,13 +398,12 @@ void LLRenderTarget::bindTarget()
{
if (mFBO)
{
- mPreviousFBO = sCurFBO;
-
stop_glerror();
+ mPreviousFBO = sCurFBO;
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
sCurFBO = mFBO;
-
+
stop_glerror();
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
@@ -418,7 +425,12 @@ void LLRenderTarget::bindTarget()
stop_glerror();
}
+ mPreviousResX = sCurResX;
+ mPreviousResY = sCurResY;
glViewport(0, 0, mResX, mResY);
+ sCurResX = mResX;
+ sCurResY = mResY;
+
sBoundTarget = this;
}
@@ -489,6 +501,20 @@ void LLRenderTarget::flush(bool fetch_depth)
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
sCurFBO = mPreviousFBO;
+
+ if (mPreviousFBO)
+ {
+ glViewport(0, 0, mPreviousResX, mPreviousResY);
+ sCurResX = mPreviousResX;
+ sCurResY = mPreviousResY;
+ }
+ else
+ {
+ glViewport(gGLViewport[0],gGLViewport[1],gGLViewport[2],gGLViewport[3]);
+ sCurResX = gGLViewport[2];
+ sCurResY = gGLViewport[3];
+ }
+
stop_glerror();
}
}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 765a727b5b..66a9874a6b 100755
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -63,6 +63,9 @@ public:
static bool sUseFBO;
static U32 sBytesAllocated;
static U32 sCurFBO;
+ static U32 sCurResX;
+ static U32 sCurResY;
+
LLRenderTarget();
~LLRenderTarget();
@@ -146,6 +149,9 @@ protected:
std::vector<U32> mInternalFormat;
U32 mFBO;
U32 mPreviousFBO;
+ U32 mPreviousResX;
+ U32 mPreviousResY;
+
U32 mDepth;
bool mStencil;
bool mUseDepth;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index b6a9a6b653..fea4ee2819 100755
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -521,7 +521,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
}
}
-GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
+GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
{
GLenum error = GL_NO_ERROR;
if (gDebugGL)
@@ -650,13 +650,15 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
}
}
-
- //copy preprocessor definitions into buffer
- for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
+
+ if (defines)
+ {
+ for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
text[count++] = (GLcharARB *) strdup(define.c_str());
}
+ }
if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
{
@@ -693,6 +695,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
*/
+ text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n");
+
//uniform declartion
for (S32 i = 0; i < texture_index_channels; ++i)
{
@@ -750,6 +754,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;
}
}
+ else
+ {
+ text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
+ }
//copy file into memory
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )
@@ -806,7 +814,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
//an error occured, print log
LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
dumpObjectLog(ret);
-
#if LL_WINDOWS
std::stringstream ostr;
//dump shader source for debugging
@@ -824,8 +831,20 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
-#endif // LL_WINDOWS
-
+#else
+ std::string str;
+
+ for (GLuint i = 0; i < count; i++) {
+ str.append(text[i]);
+
+ if (i % 128 == 0)
+ {
+ LL_WARNS("ShaderLoading") << str << llendl;
+ str = "";
+ }
+ }
+#endif
+
ret = 0;
}
}
@@ -854,7 +873,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (shader_level > 1)
{
shader_level--;
- return loadShaderFile(filename,shader_level,type,texture_index_channels);
+ return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);
}
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
}
@@ -958,7 +977,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedAttribs.push_back("texcoord3");
mReservedAttribs.push_back("diffuse_color");
mReservedAttribs.push_back("emissive");
- mReservedAttribs.push_back("binormal");
+ mReservedAttribs.push_back("tangent");
mReservedAttribs.push_back("weight");
mReservedAttribs.push_back("weight4");
mReservedAttribs.push_back("clothing");
@@ -1055,6 +1074,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("minimum_alpha");
+ mReservedUniforms.push_back("emissive_brightness");
mReservedUniforms.push_back("shadow_matrix");
mReservedUniforms.push_back("env_mat");
@@ -1115,6 +1135,12 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("lightMap");
mReservedUniforms.push_back("bloomMap");
mReservedUniforms.push_back("projectionMap");
+
+ mReservedUniforms.push_back("global_gamma");
+ mReservedUniforms.push_back("texture_gamma");
+
+ mReservedUniforms.push_back("specular_color");
+ mReservedUniforms.push_back("env_intensity");
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 7a16b7c20f..c049e935b8 100755
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -109,6 +109,7 @@ public:
GLOW_DELTA,
MINIMUM_ALPHA,
+ EMISSIVE_BRIGHTNESS,
DEFERRED_SHADOW_MATRIX,
DEFERRED_ENV_MAT,
@@ -164,6 +165,13 @@ public:
DEFERRED_LIGHT,
DEFERRED_BLOOM,
DEFERRED_PROJECTION,
+
+ GLOBAL_GAMMA,
+ TEXTURE_GAMMA,
+
+ SPECULAR_COLOR,
+ ENVIRONMENT_INTENSITY,
+
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
@@ -176,7 +184,7 @@ public:
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
- GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1);
+ GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::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
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 4909b43e8a..01541026b1 100755
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -342,13 +342,32 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
sizeof(LLVector2), // TYPE_TEXCOORD3,
sizeof(LLColor4U), // TYPE_COLOR,
sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently
- sizeof(LLVector4), // TYPE_BINORMAL,
+ sizeof(LLVector4), // TYPE_TANGENT,
sizeof(F32), // TYPE_WEIGHT,
sizeof(LLVector4), // TYPE_WEIGHT4,
sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
};
+static std::string vb_type_name[] =
+{
+ "TYPE_VERTEX",
+ "TYPE_NORMAL",
+ "TYPE_TEXCOORD0",
+ "TYPE_TEXCOORD1",
+ "TYPE_TEXCOORD2",
+ "TYPE_TEXCOORD3",
+ "TYPE_COLOR",
+ "TYPE_EMISSIVE",
+ "TYPE_TANGENT",
+ "TYPE_WEIGHT",
+ "TYPE_WEIGHT4",
+ "TYPE_CLOTHWEIGHT",
+ "TYPE_TEXTURE_INDEX",
+ "TYPE_MAX",
+ "TYPE_INDEX",
+};
+
U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
{
GL_TRIANGLES,
@@ -523,16 +542,16 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
}
- if (sLastMask & MAP_BINORMAL)
+ if (sLastMask & MAP_TANGENT)
{
- if (!(data_mask & MAP_BINORMAL))
+ if (!(data_mask & MAP_TANGENT))
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
}
- else if (data_mask & MAP_BINORMAL)
+ else if (data_mask & MAP_TANGENT)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -593,8 +612,9 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
glNormalPointer(GL_FLOAT, 0, norm[0].mV);
}
-
+ LLGLSLShader::startProfile();
glDrawArrays(sGLMode[mode], 0, count);
+ LLGLSLShader::stopProfile(count, mode);
}
//static
@@ -631,7 +651,9 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
glVertexPointer(3, GL_FLOAT, 16, pos);
}
+ LLGLSLShader::startProfile();
glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
+ LLGLSLShader::stopProfile(num_indices, mode);
}
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
@@ -731,9 +753,14 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
stop_glerror();
+ LLGLSLShader::startProfile();
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
+ LLGLSLShader::stopProfile(count, mode);
stop_glerror();
+
+
+
placeFence();
}
@@ -777,8 +804,10 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
}
stop_glerror();
+ LLGLSLShader::startProfile();
glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
((U16*) getIndicesPointer()) + indices_offset);
+ LLGLSLShader::stopProfile(count, mode);
stop_glerror();
placeFence();
}
@@ -820,9 +849,12 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
LLFastTimer t2(FTM_GL_DRAW_ARRAYS);
- stop_glerror();
- glDrawArrays(sGLMode[mode], first, count);
- }
+ stop_glerror();
+ LLGLSLShader::startProfile();
+ glDrawArrays(sGLMode[mode], first, count);
+ LLGLSLShader::stopProfile(count, mode);
+ }
+
stop_glerror();
placeFence();
}
@@ -1322,7 +1354,7 @@ void LLVertexBuffer::setupVertexArray()
2, //TYPE_TEXCOORD3,
4, //TYPE_COLOR,
4, //TYPE_EMISSIVE,
- 3, //TYPE_BINORMAL,
+ 4, //TYPE_TANGENT,
1, //TYPE_WEIGHT,
4, //TYPE_WEIGHT4,
4, //TYPE_CLOTHWEIGHT,
@@ -1339,7 +1371,7 @@ void LLVertexBuffer::setupVertexArray()
GL_FLOAT, //TYPE_TEXCOORD3,
GL_UNSIGNED_BYTE, //TYPE_COLOR,
GL_UNSIGNED_BYTE, //TYPE_EMISSIVE,
- GL_FLOAT, //TYPE_BINORMAL,
+ GL_FLOAT, //TYPE_TANGENT,
GL_FLOAT, //TYPE_WEIGHT,
GL_FLOAT, //TYPE_WEIGHT4,
GL_FLOAT, //TYPE_CLOTHWEIGHT,
@@ -1356,7 +1388,7 @@ void LLVertexBuffer::setupVertexArray()
false, //TYPE_TEXCOORD3,
false, //TYPE_COLOR,
false, //TYPE_EMISSIVE,
- false, //TYPE_BINORMAL,
+ false, //TYPE_TANGENT,
false, //TYPE_WEIGHT,
false, //TYPE_WEIGHT4,
false, //TYPE_CLOTHWEIGHT,
@@ -1373,7 +1405,7 @@ void LLVertexBuffer::setupVertexArray()
GL_FALSE, //TYPE_TEXCOORD3,
GL_TRUE, //TYPE_COLOR,
GL_TRUE, //TYPE_EMISSIVE,
- GL_FALSE, //TYPE_BINORMAL,
+ GL_FALSE, //TYPE_TANGENT,
GL_FALSE, //TYPE_WEIGHT,
GL_FALSE, //TYPE_WEIGHT4,
GL_FALSE, //TYPE_CLOTHWEIGHT,
@@ -2038,14 +2070,21 @@ bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 inde
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
}
-
+bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
+{
+ return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range);
+}
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
}
-bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
+bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
- return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range);
+ return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
+}
+bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
+{
+ return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
{
@@ -2200,7 +2239,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if ((data_mask & required_mask) != required_mask)
{
- llerrs << "Shader consumption mismatches data provision." << llendl;
+ llwarns << "Shader consumption mismatches data provision." << llendl;
}
}
}
@@ -2318,6 +2357,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
{
+ for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i)
+ {
+ U32 mask = 1 << i;
+ if (mask & data_mask && !(mask & mTypeMask))
+ { //bit set in data_mask, but not set in mTypeMask
+ llwarns << "Missing required component " << vb_type_name[i] << llendl;
+ }
+ }
llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
}
@@ -2347,11 +2394,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
}
- if (data_mask & MAP_BINORMAL)
+ if (data_mask & MAP_TANGENT)
{
- S32 loc = TYPE_BINORMAL;
- void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]);
- glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr);
+ S32 loc = TYPE_TANGENT;
+ void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
+ glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
}
if (data_mask & MAP_TEXCOORD0)
{
@@ -2429,10 +2476,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
- if (data_mask & MAP_BINORMAL)
+ if (data_mask & MAP_TANGENT)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
if (data_mask & MAP_TEXCOORD0)
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 11fa4ab6a0..04806c1d8c 100755
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -174,7 +174,7 @@ public:
TYPE_TEXCOORD3,
TYPE_COLOR,
TYPE_EMISSIVE,
- TYPE_BINORMAL,
+ TYPE_TANGENT,
TYPE_WEIGHT,
TYPE_WEIGHT4,
TYPE_CLOTHWEIGHT,
@@ -192,7 +192,7 @@ public:
MAP_COLOR = (1<<TYPE_COLOR),
MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
// These use VertexAttribPointer and should possibly be made generic
- MAP_BINORMAL = (1<<TYPE_BINORMAL),
+ MAP_TANGENT = (1<<TYPE_TANGENT),
MAP_WEIGHT = (1<<TYPE_WEIGHT),
MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
@@ -250,8 +250,10 @@ public:
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
- bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool 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);
diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp
index 0620e0f52d..f3a526faeb 100755
--- a/indra/llui/lllocalcliprect.cpp
+++ b/indra/llui/lllocalcliprect.cpp
@@ -33,7 +33,7 @@
LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled)
- : mScissorState(GL_SCISSOR_TEST),
+: mScissorState(GL_SCISSOR_TEST),
mEnabled(enabled)
{
if (mEnabled)
@@ -100,10 +100,10 @@ void LLScreenClipRect::updateScissorRegion()
// LLLocalClipRect
//---------------------------------------------------------------------------
LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */)
- : LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,
- rect.mTop + LLFontGL::sCurOrigin.mY,
- rect.mRight + LLFontGL::sCurOrigin.mX,
- rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
+: LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,
+ rect.mTop + LLFontGL::sCurOrigin.mY,
+ rect.mRight + LLFontGL::sCurOrigin.mX,
+ rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
{}
LLLocalClipRect::~LLLocalClipRect()
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index 3ad5ad7d42..6322da9123 100755
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -1309,10 +1309,8 @@ bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, name_stack_t
void LLXUIParser::parserWarning(const std::string& message)
{
#ifdef LL_WINDOWS
- // use Visual Studo friendly formatting of output message for easy access to originating xml
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
+ // use Visual Studio friendly formatting of output message for easy access to originating xml
+ LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()));
#else
Parser::parserWarning(message);
#endif
@@ -1321,9 +1319,8 @@ void LLXUIParser::parserWarning(const std::string& message)
void LLXUIParser::parserError(const std::string& message)
{
#ifdef LL_WINDOWS
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
+ // use Visual Studio friendly formatting of output message for easy access to originating xml
+ LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()));
#else
Parser::parserError(message);
#endif
@@ -1640,10 +1637,8 @@ bool LLSimpleXUIParser::processText()
void LLSimpleXUIParser::parserWarning(const std::string& message)
{
#ifdef LL_WINDOWS
- // use Visual Studo friendly formatting of output message for easy access to originating xml
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
+ // use Visual Studio friendly formatting of output message for easy access to originating xml
+ LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()));
#else
Parser::parserWarning(message);
#endif
@@ -1652,9 +1647,8 @@ void LLSimpleXUIParser::parserWarning(const std::string& message)
void LLSimpleXUIParser::parserError(const std::string& message)
{
#ifdef LL_WINDOWS
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
+ // use Visual Studio friendly formatting of output message for easy access to originating xml
+ LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()));
#else
Parser::parserError(message);
#endif
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index c5041d434c..e00596cdb5 100755
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -134,7 +134,7 @@ LLDir_Mac::LLDir_Mac()
{
mOSCacheDir = *cachedir;
- //SPATTERS TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away.
+ //Aura TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away.
CreateDirectory(mOSCacheDir, secondLifeString, NULL);
}
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 462d1cce06..6184095957 100755
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -131,7 +131,7 @@ LLDir_Win32::LLDir_Win32()
mAppRODataDir = mExecutableDir;
}
- llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;
+// llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp
index 03d2cc25e3..306d7d8ec7 100755
--- a/indra/llvfs/llvfile.cpp
+++ b/indra/llvfs/llvfile.cpp
@@ -135,7 +135,7 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S
data = NULL;
}
else
- {
+ {
data = (U8*) ll_aligned_malloc_16(file_size);
file.read(data, file_size); /* Flawfinder: ignore */
diff --git a/indra/llvfs/llvfs_objc.mm b/indra/llvfs/llvfs_objc.mm
index 4f9e2f81e9..47b0e73978 100755
--- a/indra/llvfs/llvfs_objc.mm
+++ b/indra/llvfs/llvfs_objc.mm
@@ -58,7 +58,7 @@ std::string* findSystemDirectory(NSSearchPathDirectory searchPathDirectory,
if ([paths count])
{
path = [paths objectAtIndex:0];
- //SPATTERS HACK: Always attempt to create directory, ignore errors.
+ //HACK: Always attempt to create directory, ignore errors.
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index ad010164eb..4c6e706119 100755
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -165,7 +165,7 @@ if (BUILD_HEADLESS)
set(llwindowheadless_HEADER_FILES
llwindowmesaheadless.h
llmousehandler.h
- )
+ )
add_library (llwindowheadless
${llwindow_SOURCE_FILES}
${llwindowheadless_SOURCE_FILES}
@@ -180,12 +180,12 @@ if (llwindow_HEADER_FILES)
list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES})
endif (llwindow_HEADER_FILES)
-list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
+ list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
-add_library (llwindow
- ${llwindow_SOURCE_FILES}
- ${viewer_SOURCE_FILES}
- )
+ add_library (llwindow
+ ${llwindow_SOURCE_FILES}
+ ${viewer_SOURCE_FILES}
+ )
if (SDL_FOUND)
set_property(TARGET llwindow
@@ -193,5 +193,5 @@ if (SDL_FOUND)
)
endif (SDL_FOUND)
-target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
+ target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index cf96f26a77..17400a203e 100755
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -42,7 +42,7 @@ list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})
add_library (llxml ${llxml_SOURCE_FILES})
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
-target_link_libraries(llxml
+target_link_libraries( llxml
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index b2c49083cb..1bb38bbf65 100755
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -79,11 +79,9 @@ void parse_string();
#define yyfree indra_free
-#if defined(__cplusplus)
-extern "C" { int yylex( void ); }
-extern "C" { int yyparse( void ); }
-extern "C" { int yyerror(const char *fmt, ...); }
-#endif
+int yylex( void );
+int yyparse( void );
+int yyerror(const char *fmt, ...);
%}
diff --git a/indra/lscript/lscript_compile/indra.y b/indra/lscript/lscript_compile/indra.y
index e4b10ffdd9..a0a034d21c 100755
--- a/indra/lscript/lscript_compile/indra.y
+++ b/indra/lscript/lscript_compile/indra.y
@@ -2,10 +2,6 @@
#include "linden_common.h"
#include "lscript_tree.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
-
int yylex(void);
int yyparse( void );
int yyerror(const char *fmt, ...);
@@ -20,9 +16,6 @@
#pragma warning( disable : 4065 ) // warning: switch statement contains 'default' but no 'case' labels
#endif
- #ifdef __cplusplus
- }
- #endif
%}
%union
diff --git a/indra/mac_crash_logger/CrashReporter.nib b/indra/mac_crash_logger/CrashReporter.nib
index a30d8d205c..e9d9e05985 100755
--- a/indra/mac_crash_logger/CrashReporter.nib
+++ b/indra/mac_crash_logger/CrashReporter.nib
Binary files differ
diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp
index 47a1e5c018..aac349bf57 100755
--- a/indra/media_plugins/winmmshim/winmm_shim.cpp
+++ b/indra/media_plugins/winmmshim/winmm_shim.cpp
@@ -56,7 +56,7 @@ void ll_winmm_shim_initialize(){
// grab winmm.dll from system path, where it should live
wsprintf(dll_path, "%s\\winmm.dll", system_path);
HMODULE winmm_handle = ::LoadLibrary(dll_path);
-
+
if (winmm_handle != NULL)
{ // we have a dll, let's get out pointers!
initialized = true;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d35180afc9..570081e8f0 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -4,6 +4,7 @@ project(viewer)
include(00-Common)
include(Boost)
+include(BuildVersion)
include(DBusGlib)
include(DirectX)
include(OpenSSL)
@@ -174,6 +175,7 @@ set(viewer_SOURCE_FILES
lldrawpoolavatar.cpp
lldrawpoolbump.cpp
lldrawpoolground.cpp
+ lldrawpoolmaterials.cpp
lldrawpoolsimple.cpp
lldrawpoolsky.cpp
lldrawpoolterrain.cpp
@@ -359,6 +361,7 @@ set(viewer_SOURCE_FILES
llmaniptranslate.cpp
llmarketplacefunctions.cpp
llmarketplacenotifications.cpp
+ llmaterialmgr.cpp
llmediactrl.cpp
llmediadataclient.cpp
llmenuoptionpathfindingrebakenavmesh.cpp
@@ -756,6 +759,7 @@ set(viewer_HEADER_FILES
lldrawpoolalpha.h
lldrawpoolavatar.h
lldrawpoolbump.h
+ lldrawpoolmaterials.h
lldrawpoolground.h
lldrawpoolsimple.h
lldrawpoolsky.h
@@ -941,6 +945,7 @@ set(viewer_HEADER_FILES
llmaniptranslate.h
llmarketplacefunctions.h
llmarketplacenotifications.h
+ llmaterialmgr.h
llmediactrl.h
llmediadataclient.h
llmenuoptionpathfindingrebakenavmesh.h
@@ -1567,7 +1572,7 @@ endif (WINDOWS)
if (OPENAL)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
-endif (OPENAL)
+endif (OPENAL)
if (FMODEX)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
@@ -1669,6 +1674,7 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/zlib1.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxplatform.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll
+ ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ca-bundle.crt
${GOOGLE_PERF_TOOLS_SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/licenses-win32.txt
${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt
@@ -1987,7 +1993,7 @@ if (DARWIN)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist"
- )
+ )
add_custom_command(
TARGET ${VIEWER_BINARY_NAME} POST_BUILD
@@ -2152,6 +2158,40 @@ if (LL_TESTS)
)
set_source_files_properties(
+ llviewerhelputil.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
+ set_source_files_properties(
+ llremoteparcelrequest.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
+ set_source_files_properties(
+ llworldmap.cpp
+ llworldmipmap.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_SOURCE_FILES
+ tests/llviewertexture_stub.cpp
+ #llviewertexturelist.cpp
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
+ set_source_files_properties(
+ llmediadataclient.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${LLPRIMITIVE_LIBRARIES}"
+ )
+
+ set_source_files_properties(
+ llagentaccess.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
+ set_source_files_properties(
lllogininstance.cpp
PROPERTIES
LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 65afb3b886..4a788a01da 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.5.4
+3.6.3
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index bb12cd59bc..9106f34e54 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2873,6 +2873,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DefaultBlankNormalTexture</key>
+ <map>
+ <key>Comment</key>
+ <string>Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>5b53359e-59dd-d8a2-04c3-9e65134da47a</string>
+ </map>
<key>DefaultFemaleAvatar</key>
<map>
<key>Comment</key>
@@ -2895,8 +2906,29 @@
<key>Value</key>
<string>Male Shape &amp; Outfit</string>
</map>
-
- <key>DefaultObjectTexture</key>
+ <key>DefaultObjectNormalTexture</key>
+ <map>
+ <key>Comment</key>
+ <string>Texture used as 'Default' in texture picker for normal map. (UUID texture reference)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>85f28839-7a1c-b4e3-d71d-967792970a7b</string>
+ </map>
+ <key>DefaultObjectSpecularTexture</key>
+ <map>
+ <key>Comment</key>
+ <string>Texture used as 'Default' in texture picker for specular map. (UUID texture reference)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string>
+ </map>
+ <key>DefaultObjectTexture</key>
<map>
<key>Comment</key>
<string>Texture used as 'Default' in texture picker. (UUID texture reference)</string>
@@ -3347,17 +3379,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>EnableTextureAtlas</key>
- <map>
- <key>Comment</key>
- <string>Whether to use texture atlas or not</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>EnableUIHints</key>
<map>
<key>Comment</key>
@@ -7711,7 +7732,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>4</integer>
+ <integer>3</integer>
</map>
<key>OctreeAlphaDistanceFactor</key>
@@ -8440,7 +8461,7 @@
<key>RenderSpotLightsInNondeferred</key>
<map>
<key>Comment</key>
- <string>Whether to support projectors as spotlights when Lighting and Shadows is disabled</string>
+ <string>Whether to support projectors as spotlights when Advanced Lighting Model is disabled</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8483,7 +8504,6 @@
<key>Value</key>
<real>1.0</real>
</map>
-
<key>RenderDeferredTreeShadowBias</key>
<map>
<key>Comment</key>
@@ -8581,7 +8601,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <real>512</real>
+ <real>1024</real>
</map>
<key>RenderSpecularResY</key>
@@ -8593,7 +8613,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <real>128</real>
+ <real>256</real>
</map>
<key>RenderSpecularExponent</key>
@@ -8611,7 +8631,7 @@
<key>RenderDeferred</key>
<map>
<key>Comment</key>
- <string>Use deferred rendering pipeline.</string>
+ <string>Use deferred rendering pipeline (Advanced Lighting Model).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8799,7 +8819,7 @@
<key>RenderAutoMaskAlphaNonDeferred</key>
<map>
<key>Comment</key>
- <string>Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode</string>
+ <string>Use alpha masks where appropriate when not using the Advanced Lighting Model</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8810,7 +8830,7 @@
<key>RenderAutoMaskAlphaDeferred</key>
<map>
<key>Comment</key>
- <string>Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode</string>
+ <string>Use alpha masks where appropriate in the Advanced Lighting Model</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -12472,17 +12492,6 @@
<key>Value</key>
<integer>3</integer>
</map>
- <key>UpdaterWillingToTest</key>
- <map>
- <key>Comment</key>
- <string>Allow upgrades to release candidate viewers with new features and fixes.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>UpdaterServiceCheckPeriod</key>
<map>
<key>Comment</key>
@@ -12866,7 +12875,6 @@
<key>Type</key>
<string>LLSD</string>
<key>Value</key>
- <string/>
</map>
<key>VFSOldSize</key>
<map>
@@ -14535,5 +14543,16 @@
<key>Value</key>
<integer>7000</integer>
</map>
+ <key>DisablePrecacheDelayAfterTeleporting</key>
+ <map>
+ <key>Comment</key>
+ <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index dd87ddb330..0899caa2af 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -25,17 +25,33 @@
#extension GL_ARB_texture_rectangle : enable
+#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 sampler2DRect depthMap;
+#if HAS_SHADOW
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow shadowMap3;
-vec4 diffuseLookup(vec2 texcoord);
+uniform vec2 shadow_res;
-uniform vec2 screen_res;
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform float shadow_bias;
+
+#endif
+
+#ifdef USE_DIFFUSE_TEX
+uniform sampler2D diffuseMap;
+#endif
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
@@ -45,11 +61,80 @@ VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
+#ifdef USE_VERTEX_COLOR
VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+#endif
+
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+uniform vec2 screen_res;
+
+vec3 calcDirectionalLight(vec3 n, vec3 l)
+{
+ float a = max(dot(n,l),0.0);
+ a = pow(a, 1.0/1.3);
+ return vec3(a,a,a);
+}
+
+vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+{
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float d = length(lv);
+
+ float da = 0.0;
+
+ if (d > 0.0 && la > 0.0 && fa > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist = d/la;
+ da = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ da *= da;
+ da *= 1.4;
+
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= max(dot(n, lv), 0.0);
+ }
+
+ return vec3(da,da,da);
+}
+
+#if HAS_SHADOW
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
+{
+ stc.xyz /= stc.w;
+ stc.z += shadow_bias;
+
+ stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+
+ return shadow*0.2;
+}
+#endif
-uniform mat4 inv_proj;
void main()
{
@@ -58,16 +143,123 @@ void main()
vec4 pos = vec4(vary_position, 1.0);
- vec4 diff= diffuseLookup(vary_texcoord0.xy);
- vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
- vec4 color = diff * col;
+#if HAS_SHADOW
+ float shadow = 0.0;
+ vec4 spos = pos;
+
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ if (spos.z < near_split.z)
+ {
+ lpos = shadow_matrix[3]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap3, lpos)*w;
+ weight += w;
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ if (spos.z < near_split.y && spos.z > far_split.z)
+ {
+ lpos = shadow_matrix[2]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
+ w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap2, lpos)*w;
+ weight += w;
+ }
+
+ if (spos.z < near_split.x && spos.z > far_split.y)
+ {
+ lpos = shadow_matrix[1]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
+ w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
+ shadow += pcfShadow(shadowMap1, lpos)*w;
+ weight += w;
+ }
+
+ if (spos.z > far_split.x)
+ {
+ lpos = shadow_matrix[0]*spos;
+
+ float w = 1.0;
+ w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
+
+ shadow += pcfShadow(shadowMap0, lpos)*w;
+ weight += w;
+ }
+
+
+ shadow /= weight;
+ }
+ else
+ {
+ shadow = 1.0;
+ }
+#endif
+
+#ifdef USE_INDEXED_TEX
+ vec4 diff = diffuseLookup(vary_texcoord0.xy);
+#else
+ vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
+#endif
+ vec4 gamma_diff = diff;
+
+ diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f));
+
+#ifdef USE_VERTEX_COLOR
+ float vertex_color_alpha = vertex_color.a;
+#else
+ float vertex_color_alpha = 1.0;
+#endif
+
+ vec3 normal = vary_norm;
+
+ vec3 l = light_position[0].xyz;
+ vec3 dlight = calcDirectionalLight(normal, l);
+ dlight = dlight * vary_directional.rgb * vary_pointlight_col;
+
+#if HAS_SHADOW
+ vec4 col = vec4(vary_ambient + dlight * shadow, vertex_color_alpha);
+#else
+ vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha);
+#endif
+
+ vec4 color = gamma_diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
+ color.rgb = pow(color.rgb, vec3(2.2));
+ col = vec4(0,0,0,0);
+
+
+ #define LIGHT_LOOP(i) col.rgb += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ color.rgb += diff.rgb * pow(vary_pointlight_col, vec3(2.2)) * col.rgb;
+
+ color.rgb = pow(color.rgb, vec3(1.0/2.2));
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl
index beb3290187..2ce44d599f 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl
@@ -47,9 +47,51 @@ VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
VARYING vec4 vertex_color;
+VARYING vec3 vary_norm;
uniform mat4 inv_proj;
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+vec3 calcDirectionalLight(vec3 n, vec3 l)
+{
+ float a = pow(max(dot(n,l),0.0), 0.7);
+ return vec3(a,a,a);
+}
+
+vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+{
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float d = dot(lv,lv);
+
+ float da = 0.0;
+
+ if (d > 0.0 && la > 0.0 && fa > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist2 = d/la;
+ da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= max(pow(dot(n, lv), 0.7), 0.0);
+ }
+
+ return vec3(da,da,da);
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
@@ -72,14 +114,33 @@ void main()
vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
- vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
+ vec3 n = vary_norm;
+ vec3 l = light_position[0].xyz;
+ vec3 dlight = calcDirectionalLight(n, l);
+ dlight = dlight * vary_directional.rgb * vary_pointlight_col;
+
+ vec4 col = vec4(vary_ambient + dlight, vertex_color.a);
vec4 color = diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
+ vec3 light_col = vec3(0,0,0);
+
+ #define LIGHT_LOOP(i) \
+ light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ color.rgb += diff.rgb * vary_pointlight_col * light_col;
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
+ color.rgb = pow(color.rgb, vec3(1.0/2.2));
frag_color = color;
//frag_color = vec4(1,0,1,1);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
index 5a0e8ff684..5f93986f1d 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
@@ -46,6 +46,7 @@ VARYING vec3 vary_pointlight_col;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
uniform float near_clip;
@@ -104,7 +105,7 @@ void main()
norm = position.xyz + normal.xyz;
norm = normalize(( trans*vec4(norm, 1.0) ).xyz-pos.xyz);
-
+ vary_norm = norm;
vec4 frag_pos = projection_matrix * pos;
gl_Position = frag_pos;
@@ -112,27 +113,18 @@ void main()
calcAtmospherics(pos.xyz);
+ //vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*diffuse_color.rgb;
-
+ vary_pointlight_col = diffuse_color.rgb;
col.rgb = vec3(0,0,0);
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
vary_ambient = col.rgb*diffuse_color.rgb;
- vary_directional = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
+ vary_directional.rgb = atmosAffectDirectionalLight(1);
- col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
+ col.rgb = col.rgb*diffuse_color.rgb;
vertex_color = col;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index cf38a2f4f7..9d3ba564cd 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -23,22 +23,41 @@
* $/LicenseInfo$
*/
+#define INDEXED 1
+#define NON_INDEXED 2
+#define NON_INDEXED_NO_COLOR 3
+
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
+uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
+
+#ifdef USE_INDEXED_TEX
void passTextureIndex();
+#endif
+
ATTRIBUTE vec3 normal;
+
+#ifdef USE_VERTEX_COLOR
ATTRIBUTE vec4 diffuse_color;
+#endif
+
ATTRIBUTE vec2 texcoord0;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+#else
+#ifdef IS_AVATAR_SKIN
+mat4 getSkinnedTransform();
+#endif
+#endif
+
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
-float calcDirectionalLight(vec3 n, vec3 l);
-
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
@@ -50,26 +69,24 @@ VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
+#ifdef USE_VERTEX_COLOR
VARYING vec4 vertex_color;
+#endif
+
VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
uniform float near_clip;
-uniform float shadow_offset;
-uniform float shadow_bias;
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
+uniform vec3 sun_dir;
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
@@ -96,53 +113,110 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= max(dot(n, lv), 0.0);
}
- return da;
+ return vec3(da,da,da);
}
void main()
{
+ vec4 pos;
+ vec3 norm;
+
//transform vertex
+#ifdef HAS_SKIN
+ mat4 trans = getObjectSkinnedTransform();
+ trans = modelview_matrix * trans;
+
+ pos = trans * vec4(position.xyz, 1.0);
+
+ norm = position.xyz + normal.xyz;
+ norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz);
+ vec4 frag_pos = projection_matrix * pos;
+ gl_Position = frag_pos;
+#else
+
+#ifdef IS_AVATAR_SKIN
+ mat4 trans = getSkinnedTransform();
+ vec4 pos_in = vec4(position.xyz, 1.0);
+ pos.x = dot(trans[0], pos_in);
+ pos.y = dot(trans[1], pos_in);
+ pos.z = dot(trans[2], pos_in);
+ pos.w = 1.0;
+
+ norm.x = dot(trans[0].xyz, normal);
+ norm.y = dot(trans[1].xyz, normal);
+ norm.z = dot(trans[2].xyz, normal);
+ norm = normalize(norm);
+
+ vec4 frag_pos = projection_matrix * pos;
+ gl_Position = frag_pos;
+#else
+ norm = normalize(normal_matrix * normal);
vec4 vert = vec4(position.xyz, 1.0);
- passTextureIndex();
- vec4 pos = (modelview_matrix * vert);
+ pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#endif
+#endif
+
+#ifdef USE_INDEXED_TEX
+ passTextureIndex();
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+#else
+ vary_texcoord0 = texcoord0;
+#endif
- vec3 norm = normalize(normal_matrix * normal);
-
- float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
- vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
-
+ vary_norm = norm;
+ vary_position = pos.xyz;
+
calcAtmospherics(pos.xyz);
+#ifndef USE_VERTEX_COLOR
+ vec4 diffuse_color = vec4(1,1,1,1);
+#endif
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
+
+ vec3 diff = diffuse_color.rgb;
+
+
+
+ vary_pointlight_col = diff;
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
- vary_pointlight_col = col.rgb*diffuse_color.rgb;
col.rgb = vec3(0,0,0);
// Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
+ col.rgb = atmosAmbient(col.rgb);
- vary_ambient = col.rgb*diffuse_color.rgb;
- vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb *= ambient;
+
+ vary_ambient = col.rgb*diff.rgb;
+
+ vary_directional.rgb = atmosAffectDirectionalLight(1.0f);
- col.rgb = col.rgb*diffuse_color.rgb;
+ col.rgb = col.rgb*diff.rgb;
+#ifdef USE_VERTEX_COLOR
vertex_color = col;
-
-
+#endif
+#ifdef HAS_SKIN
+ vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
+#else
+
+#ifdef IS_AVATAR_SKIN
+ vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
+#else
pos = modelview_projection_matrix * vert;
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
+#endif
+#endif
+
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
index 81961d7746..3f90600ace 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
@@ -39,7 +39,12 @@ void main()
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+
vec4 p = projection_matrix * vec4(pos, 1.0);
+#if !DEPTH_CLAMP
p.z = max(p.z, -p.w+0.01);
gl_Position = p;
+#else
+ gl_Position = p;
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
index 5f395801e5..c8ddefac26 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
@@ -47,6 +47,7 @@ VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
uniform float near_clip;
@@ -112,6 +113,7 @@ void main()
norm.y = dot(trans[1].xyz, normal);
norm.z = dot(trans[2].xyz, normal);
norm = normalize(norm);
+ vary_norm = norm;
vec4 frag_pos = projection_matrix * pos;
gl_Position = frag_pos;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index bfd9b9b3eb..bcccbf77d2 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -34,6 +34,12 @@ uniform sampler2D diffuseMap;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -46,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(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
index 3686f2f647..b809b73973 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
@@ -31,12 +31,16 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
void main()
{
frag_color = vec4(1,1,1,1);
+#if !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/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
index 23feb09d72..bde1ad4e9f 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
@@ -31,7 +31,9 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
void main()
{
@@ -51,9 +53,13 @@ void main()
norm = normalize(norm);
pos = projection_matrix * pos;
+#if !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/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index f400eb7a5b..968a5f6b3d 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -46,11 +46,6 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec3 getKern(int i)
-{
- return kern[i];
-}
-
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -64,18 +59,53 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
void main()
{
vec2 tc = vary_fragcoord.xy;
vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = decode_normal(norm.xy); // unpack norm
+
vec3 pos = getPosition(tc).xyz;
vec4 ccol = texture2DRect(lightMap, tc).rgba;
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
dlt /= max(-pos.z*dist_factor, 1.0);
- vec2 defined_weight = getKern(0).xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
+ vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
vec4 col = defined_weight.xyxx * ccol;
// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
@@ -85,28 +115,33 @@ void main()
float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
tc_mod -= floor(tc_mod);
tc_mod *= 2.0;
- tc += ( (tc_mod - 0.5) * getKern(1).z * dlt * 0.5 );
+ tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
for (int i = 1; i < 4; i++)
{
- vec2 samptc = tc + getKern(i).z*dlt;
- vec3 samppos = getPosition(samptc).xyz;
+ vec2 samptc = tc + kern[i].z*dlt;
+ 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)*getKern(i).xyxx;
- defined_weight += getKern(i).xy;
+ col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
+ defined_weight += kern[i].xy;
}
}
+
for (int i = 1; i < 4; i++)
{
- vec2 samptc = tc - getKern(i).z*dlt;
- vec3 samppos = getPosition(samptc).xyz;
+ vec2 samptc = tc - kern[i].z*dlt;
+ 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)*getKern(i).xyxx;
- defined_weight += getKern(i).xy;
+ col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
+ defined_weight += kern[i].xy;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 23c4ea2fff..595c11fae2 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -39,6 +39,12 @@ VARYING vec3 vary_mat2;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
@@ -52,5 +58,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(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
index 8ba75010a2..10144f3e16 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
@@ -30,7 +30,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 binormal;
+ATTRIBUTE vec4 tangent;
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
@@ -52,8 +52,8 @@ void main()
vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
- vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
- vec3 t = cross(b, n);
+ vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
+ vec3 b = cross(n, t) * tangent.w;
vary_mat0 = vec3(t.x, b.x, n.x);
vary_mat1 = vec3(t.y, b.y, n.y);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
index c8d38bb8f7..9f9749394e 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
@@ -31,7 +31,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 binormal;
+ATTRIBUTE vec4 tangent;
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
@@ -46,8 +46,8 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vec3 n = normalize(normal_matrix * normal);
- vec3 b = normalize(normal_matrix * binormal);
- vec3 t = cross(b, n);
+ vec3 t = normalize(normal_matrix * tangent.xyz);
+ vec3 b = cross(n, t) * tangent.w;
vary_mat0 = vec3(t.x, b.x, n.x);
vary_mat1 = vec3(t.y, b.y, n.y);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index c1fa9e4aac..7930b5d18b 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -37,6 +37,12 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
@@ -49,6 +55,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(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index 4c68123fac..59d109b886 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -36,6 +36,12 @@ uniform float minimum_alpha;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
@@ -48,5 +54,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(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
index ad65c7d330..37d70a2412 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -37,6 +37,12 @@ uniform sampler2D diffuseMap;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -49,6 +55,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(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 86390bdd83..6befb1bd8b 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -35,6 +35,12 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
@@ -42,6 +48,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(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index 788b966af8..adc361d7a2 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -33,13 +33,22 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+
void main()
{
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
+
+ vec3 spec;
+ spec.rgb = vec3(vertex_color.a);
frag_data[0] = vec4(col, 0.0);
- 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
+ frag_data[1] = vec4(spec, vertex_color.a); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
index 76d29b1df7..3c026796c8 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
@@ -47,6 +47,6 @@ void main()
passTextureIndex();
vary_normal = normalize(normal_matrix * normal);
-
+
vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
index 6aa4d7b4ed..ed02c4a481 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
@@ -42,7 +42,7 @@ void main()
float shadow = 1.0;
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
-
+ color.rgb = pow(color.rgb, vec3(2.2));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 36433a5827..dc1dead656 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -31,6 +31,10 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+#if !HAS_DIFFUSE_LOOKUP
+uniform sampler2D diffuseMap;
+#endif
+
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -40,14 +44,20 @@ vec3 fullbrightScaleSoftClip(vec3 light);
void main()
{
- float shadow = 1.0;
-
+#if HAS_DIFFUSE_LOOKUP
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
+#else
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy)*vertex_color;
+#endif
+
+ color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
+ color.rgb = pow(color.rgb, vec3(1.0/2.2));
+
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
new file mode 100644
index 0000000000..b0db9876d3
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -0,0 +1,72 @@
+/**
+ * @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$
+ */
+
+
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#ifndef diffuseLookup
+uniform sampler2D diffuseMap;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
+
+uniform samplerCube environmentMap;
+
+vec3 fullbrightShinyAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+void main()
+{
+#if HAS_DIFFUSE_LOOKUP
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+#else
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+#endif
+
+
+ color.rgb *= vertex_color.rgb;
+
+ vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
+ color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+
+ color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
+
+ color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+ color.rgb = fullbrightScaleSoftClip(color.rgb);
+
+ color.a = 1.0;
+
+ color.rgb = pow(color.rgb, vec3(1.0/2.2));
+
+ frag_color = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
new file mode 100644
index 0000000000..34bd8d445a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
@@ -0,0 +1,67 @@
+/**
+ * @file fullbrightShinyV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 texture_matrix1;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+
+void calcAtmospherics(vec3 inPositionEye);
+
+uniform vec4 origin;
+
+
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
+
+
+void main()
+{
+ //transform vertex
+ vec4 vert = vec4(position.xyz,1.0);
+ passTextureIndex();
+ vec4 pos = (modelview_matrix * vert);
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+
+ vec3 norm = normalize(normal_matrix * normal);
+ vec3 ref = reflect(pos.xyz, -norm);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
+
+ calcAtmospherics(pos.xyz);
+
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index 2e6982d101..3f09a15375 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -57,8 +57,6 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
calcAtmospherics(pos.xyz);
-
- vertex_color = diffuse_color;
-
+ vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
new file mode 100644
index 0000000000..618ea747f5
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -0,0 +1,696 @@
+/**
+ * @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$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+uniform float emissive_brightness;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#if HAS_SUN_SHADOW
+
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow shadowMap3;
+
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform vec2 shadow_res;
+uniform float shadow_bias;
+
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
+{
+ stc.xyz /= stc.w;
+ stc.z += shadow_bias;
+
+ stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+
+ return shadow*0.2;
+}
+
+#endif
+
+uniform samplerCube environmentMap;
+uniform sampler2D lightFunc;
+
+// Inputs
+uniform vec4 morphFactor;
+uniform vec3 camPosLocal;
+//uniform vec4 camPosWorld;
+uniform vec4 gamma;
+uniform vec4 lightnorm;
+uniform vec4 sunlight_color;
+uniform vec4 ambient;
+uniform vec4 blue_horizon;
+uniform vec4 blue_density;
+uniform float haze_horizon;
+uniform float haze_density;
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+uniform vec4 glow;
+uniform float scene_light_strength;
+uniform mat3 env_mat;
+uniform mat3 ssao_effect_mat;
+
+uniform vec3 sun_dir;
+VARYING vec2 vary_fragcoord;
+
+VARYING vec3 vary_position;
+
+vec3 vary_PositionEye;
+
+vec3 vary_SunlitColor;
+vec3 vary_AmblitColor;
+vec3 vary_AdditiveColor;
+vec3 vary_AtmosAttenuation;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+vec3 calcDirectionalLight(vec3 n, vec3 l)
+{
+ float a = max(dot(n,l),0.0);
+ return vec3(a,a,a);
+}
+
+
+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)
+{
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float d = length(lv);
+
+ float da = 1.0;
+
+ vec3 col = vec3(0,0,0);
+
+ if (d > 0.0 && la > 0.0 && fa > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist = d/la;
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 1.4;
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= max(dot(n, lv), 0.0);
+
+ float lit = max(da * dist_atten, 0.0);
+
+ col = light_col*lit*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;
+ 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);
+ //col += spec.rgb;
+ }
+ }
+ }
+
+ return max(col, vec3(0.0,0.0,0.0));
+
+}
+
+vec4 getPosition_d(vec2 pos_screen, float depth)
+{
+ vec2 sc = pos_screen.xy*2.0;
+ sc /= screen_res;
+ sc -= vec2(1.0,1.0);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
+
+vec3 getPositionEye()
+{
+ return vary_PositionEye;
+}
+vec3 getSunlitColor()
+{
+ return vary_SunlitColor;
+}
+vec3 getAmblitColor()
+{
+ return vary_AmblitColor;
+}
+vec3 getAdditiveColor()
+{
+ return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+ return vary_AtmosAttenuation;
+}
+
+void setPositionEye(vec3 v)
+{
+ vary_PositionEye = v;
+}
+
+void setSunlitColor(vec3 v)
+{
+ vary_SunlitColor = v;
+}
+
+void setAmblitColor(vec3 v)
+{
+ vary_AmblitColor = v;
+}
+
+void setAdditiveColor(vec3 v)
+{
+ vary_AdditiveColor = v;
+}
+
+void setAtmosAttenuation(vec3 v)
+{
+ vary_AtmosAttenuation = v;
+}
+
+void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
+
+ vec3 P = inPositionEye;
+ setPositionEye(P);
+
+ vec3 tmpLightnorm = lightnorm.xyz;
+
+ vec3 Pn = normalize(P);
+ float Plen = length(P);
+
+ vec4 temp1 = vec4(0);
+ vec3 temp2 = vec3(0);
+ vec4 blue_weight;
+ vec4 haze_weight;
+ vec4 sunlight = sunlight_color;
+ vec4 light_atten;
+
+ //sunlight attenuation effect (hue and brightness) due to atmosphere
+ //this is used later for sunlight modulation at various altitudes
+ light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ //I had thought blue_density and haze_density should have equal weighting,
+ //but attenuation due to haze_density tends to seem too strong
+
+ temp1 = blue_density + vec4(haze_density);
+ blue_weight = blue_density / temp1;
+ haze_weight = vec4(haze_density) / temp1;
+
+ //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
+ temp2.y = max(0.0, tmpLightnorm.y);
+ temp2.y = 1. / temp2.y;
+ sunlight *= exp( - light_atten * temp2.y);
+
+ // main atmospheric scattering line integral
+ temp2.z = Plen * density_multiplier;
+
+ // Transparency (-> temp1)
+ // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
+ // compiler gets confused.
+ temp1 = exp(-temp1 * temp2.z * distance_multiplier);
+
+ //final atmosphere attenuation factor
+ setAtmosAttenuation(temp1.rgb);
+
+ //compute haze glow
+ //(can use temp2.x as temp because we haven't used it yet)
+ temp2.x = dot(Pn, tmpLightnorm.xyz);
+ temp2.x = 1. - temp2.x;
+ //temp2.x is 0 at the sun and increases away from sun
+ temp2.x = max(temp2.x, .03); //was glow.y
+ //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ temp2.x *= glow.x;
+ //higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ temp2.x = pow(temp2.x, glow.z);
+ //glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ //add "minimum anti-solar illumination"
+ temp2.x += .25;
+
+ //increase ambient when there are more clouds
+ vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
+
+ /* decrease value and saturation (that in HSV, not HSL) for occluded areas
+ * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
+ * // The following line of code performs the equivalent of:
+ * float ambAlpha = tmpAmbient.a;
+ * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
+ * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
+ * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
+ */
+ tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
+
+ //haze color
+ setAdditiveColor(
+ vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+ + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+ + tmpAmbient)));
+
+ //brightness of surface both sunlight and ambient
+ setSunlitColor(vec3(sunlight * .5));
+ setAmblitColor(vec3(tmpAmbient * .25));
+ setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
+}
+
+vec3 atmosLighting(vec3 light)
+{
+ light *= getAtmosAttenuation().r;
+ light += getAdditiveColor();
+ return (2.0 * light);
+}
+
+vec3 atmosTransport(vec3 light) {
+ light *= getAtmosAttenuation().r;
+ light += getAdditiveColor() * 2.0;
+ return light;
+}
+vec3 atmosGetDiffuseSunlightColor()
+{
+ return getSunlitColor();
+}
+
+vec3 scaleDownLight(vec3 light)
+{
+ return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
+}
+
+vec3 scaleUpLight(vec3 light)
+{
+ return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
+}
+
+vec3 atmosAmbient(vec3 light)
+{
+ return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
+}
+
+vec3 atmosAffectDirectionalLight(float lightIntensity)
+{
+ return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
+}
+
+vec3 scaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
+ vec3 ones = vec3(1.0f, 1.0f, 1.0f);
+
+ light = ones - clamp(light, zeroes, ones);
+ light = ones - pow(light, gamma.xxx);
+
+ return light;
+}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ float brightness = dot(light.rgb, vec3(0.33333));
+
+ return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
+
+#else
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+#endif
+
+uniform sampler2D diffuseMap;
+
+#if HAS_NORMAL_MAP
+uniform sampler2D bumpMap;
+#endif
+
+#if 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
+
+#if 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;
+
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
+void main()
+{
+ vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
+ diffcol.rgb *= vertex_color.rgb;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+ if (diffcol.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ vec3 old_diffcol = diffcol.rgb;
+ diffcol.rgb = pow(diffcol.rgb, vec3(2.2));
+#endif
+
+#if 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
+
+#if 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 = tnorm;
+ norm.xyz = normalize(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;
+#if 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 RGBA
+ vec3 pos = vary_position;
+
+#if HAS_SUN_SHADOW
+ float shadow = 0.0;
+
+ vec4 spos = vec4(pos,1.0);
+
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ if (spos.z < near_split.z)
+ {
+ lpos = shadow_matrix[3]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap3, lpos)*w;
+ weight += w;
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ if (spos.z < near_split.y && spos.z > far_split.z)
+ {
+ lpos = shadow_matrix[2]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
+ w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap2, lpos)*w;
+ weight += w;
+ }
+
+ if (spos.z < near_split.x && spos.z > far_split.y)
+ {
+ lpos = shadow_matrix[1]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
+ w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
+ shadow += pcfShadow(shadowMap1, lpos)*w;
+ weight += w;
+ }
+
+ if (spos.z > far_split.x)
+ {
+ lpos = shadow_matrix[0]*spos;
+
+ float w = 1.0;
+ w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
+
+ shadow += pcfShadow(shadowMap0, lpos)*w;
+ weight += w;
+ }
+
+
+ shadow /= weight;
+ }
+ else
+ {
+ shadow = 1.0;
+ }
+#else
+ float shadow = 1.0;
+#endif
+
+ spec = final_specular;
+ vec4 diffuse = final_color;
+ float envIntensity = final_normal.z;
+
+ vec3 col = vec3(0.0f,0.0f,0.0f);
+
+ float bloom = 0.0;
+ calcAtmospherics(pos.xyz, 1.0);
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+ float da =dot(norm.xyz, sun_dir.xyz);
+ float final_da = da;
+ final_da = min(final_da, shadow);
+ final_da = max(final_da, diffuse.a);
+ final_da = max(final_da, 0.0f);
+
+ col.rgb = atmosAmbient(col);
+
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb *= ambient;
+
+ col.rgb = col.rgb + atmosAffectDirectionalLight(pow(final_da, 1.0/1.3));
+ col.rgb *= old_diffcol.rgb;
+
+
+ float glare = 0.0;
+
+ if (spec.a > 0.0) // specular reflection
+ {
+ // the old infinite-sky shiny reflection
+ //
+
+ float sa = dot(refnormpersp, sun_dir.xyz);
+ vec3 dumbshiny = vary_SunlitColor*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);
+
+ col += spec_contrib;
+ }
+
+ col = mix(col.rgb, old_diffcol.rgb, diffuse.a);
+
+ if (envIntensity > 0.0)
+ {
+ //add environmentmap
+ vec3 env_vec = env_mat * refnormpersp;
+
+ vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+
+ col = mix(col.rgb, refcol,
+ envIntensity);
+
+ float cur_glare = max(refcol.r, refcol.g);
+ cur_glare = max(cur_glare, refcol.b);
+ cur_glare *= envIntensity*4.0;
+ glare += cur_glare;
+ }
+
+ col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
+ col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+
+ //convert to linear space before adding local lights
+ col = pow(col, vec3(2.2));
+
+
+ vec3 npos = normalize(-pos.xyz);
+
+ #define LIGHT_LOOP(i) col.rgb = col.rgb + calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+
+ //convert to gamma space for display on screen
+ col.rgb = pow(col.rgb, vec3(1.0/2.2));
+
+ frag_color.rgb = col.rgb;
+ glare = min(glare, 1.0);
+ frag_color.a = max(diffcol.a,glare)*vertex_color.a;
+
+#else
+ frag_data[0] = final_color;
+ frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
new file mode 100644
index 0000000000..b25032866b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -0,0 +1,144 @@
+/**
+ * @file bumpV.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$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+#if 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 !HAS_SKIN
+uniform mat4 modelview_matrix;
+#endif
+
+VARYING vec3 vary_position;
+
+#endif
+
+uniform mat4 texture_matrix0;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+
+#if HAS_NORMAL_MAP
+ATTRIBUTE vec4 tangent;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+
+VARYING vec2 vary_texcoord1;
+#else
+VARYING vec3 vary_normal;
+#endif
+
+#if HAS_SPECULAR_MAP
+ATTRIBUTE vec2 texcoord2;
+VARYING vec2 vary_texcoord2;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+#if 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
+
+ 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;
+
+#if HAS_NORMAL_MAP
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+#endif
+
+#if HAS_SPECULAR_MAP
+ vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+#endif
+
+#if HAS_SKIN
+ vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+#if HAS_NORMAL_MAP
+ vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
+ vec3 b = cross(n, t)*tangent.w;
+
+ vary_mat0 = vec3(t.x, b.x, n.x);
+ vary_mat1 = vec3(t.y, b.y, n.y);
+ vary_mat2 = vec3(t.z, b.z, n.z);
+#else //HAS_NORMAL_MAP
+vary_normal = n;
+#endif //HAS_NORMAL_MAP
+#else //HAS_SKIN
+ vec3 n = normalize(normal_matrix * normal);
+#if HAS_NORMAL_MAP
+ vec3 t = normalize(normal_matrix * tangent.xyz);
+ vec3 b = cross(n,t)*tangent.w;
+ //vec3 t = cross(b,n) * binormal.w;
+
+ vary_mat0 = vec3(t.x, b.x, n.x);
+ vary_mat1 = vec3(t.y, b.y, n.y);
+ vary_mat2 = vec3(t.z, b.z, n.z);
+#else //HAS_NORMAL_MAP
+ vary_normal = n;
+#endif //HAS_NORMAL_MAP
+#endif //HAS_SKIN
+
+ vertex_color = diffuse_color;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+#if !HAS_SKIN
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+#endif
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 7e79317543..868526d457 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -56,6 +56,40 @@ uniform float far_z;
uniform mat4 inv_proj;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -79,7 +113,7 @@ void main()
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+ norm = decode_normal(norm.xy); // unpack norm
norm = normalize(norm);
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
@@ -93,9 +127,9 @@ void main()
bool light_contrib = (i < light_count);
vec3 lv = light[i].xyz-pos;
- float dist2 = dot(lv,lv);
- dist2 /= light[i].w;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= light[i].w;
+ if (dist > 1.0)
{
light_contrib = false;
}
@@ -110,27 +144,39 @@ void main()
{
lv = normalize(lv);
da = dot(norm, lv);
-
+
float fa = light_col[i].a+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
dist_atten *= noise;
float lit = da * dist_atten;
-
+
vec3 col = light_col[i].rgb*lit*diff;
+
//vec3 col = vec3(dist2, light_col[i].a, lit);
if (spec.a > 0.0)
{
+ lit = min(da*6.0, 1.0) * dist_atten;
//vec3 ref = dot(pos+lv, norm);
-
- float sa = dot(normalize(lv+npos),norm);
-
- if (sa > 0.0)
+ 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)
{
- sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
- sa *= noise;
- col += da*sa*light_col[i].rgb*spec.rgb;
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += lit*scol*light_col[i].rgb*spec.rgb;
+ //col += spec.rgb;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index bff87cb6aa..97bf49a605 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -40,6 +40,7 @@ uniform sampler2DRect normalMap;
uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -66,9 +67,49 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(pow(col.rgb, vec3(2.2)), col.a);
+}
+
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
@@ -84,6 +125,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -101,6 +143,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
@@ -134,15 +177,17 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = center.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0, norm.z);
+ float envIntensity = norm.z;
+
+ norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -156,7 +201,10 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 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;
+
if (dist_atten <= 0.0)
{
discard;
@@ -169,7 +217,8 @@ void main()
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
+ vec3 dlit = vec3(0, 0, 0);
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -187,14 +236,13 @@ void main()
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
- vec3 lcol = color.rgb * plcol.rgb * plcol.a;
+ dlit = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
- col = lcol*lit*diff_tex;
+ col = dlit*lit*diff_tex;
amb_da += (da*0.5)*proj_ambiance;
}
-
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
@@ -203,14 +251,39 @@ void main()
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;
+ col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;
}
vec4 spec = texture2DRect(specularRect, frag.xy);
+
if (spec.a > 0.0)
{
+ 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)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb;
+ //col += spec.rgb;
+ }
+ }
+
+ if (envIntensity > 0.0)
+ {
vec3 ref = reflect(normalize(pos), norm);
//project from point pos in direction ref to plane proj_p, proj_n
@@ -227,8 +300,9 @@ void main()
{
stc.xy /= stc.w;
- float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+ float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
+ //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
@@ -236,8 +310,7 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
+ col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;
}
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 75757b26c8..caf20ce707 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -54,6 +54,40 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
uniform vec4 viewport;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -76,15 +110,15 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+ norm = decode_normal(norm.xy); // unpack norm
float da = dot(norm, lv);
if (da < 0.0)
{
@@ -99,20 +133,33 @@ void main()
vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
float fa = falloff+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
- float lit = da * dist_atten * noise;
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+ float lit = da * dist_atten * noise;
+
col = color.rgb*lit*col;
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
{
- float sa = dot(normalize(lv-normalize(pos)),norm);
- if (sa > 0.0)
+ lit = min(da*6.0, 1.0) * dist_atten;
+
+ vec3 npos = -normalize(pos);
+ 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)
{
- sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
- sa *= noise;
- col += da*sa*color.rgb*spec.rgb;
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += lit*scol*color.rgb*spec.rgb;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
index 9491421236..a5625fbc16 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
@@ -37,7 +37,7 @@ VARYING vec3 trans_center;
void main()
{
//transform vertex
- vec3 p = position*sqrt(size)+center;
+ 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;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
new file mode 100644
index 0000000000..6f2cfae6d2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -0,0 +1,46 @@
+/**
+ * @file postDeferredGammaCorrect.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
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+
+uniform vec2 screen_res;
+VARYING vec2 vary_fragcoord;
+
+uniform float texture_gamma;
+
+void main()
+{
+ vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
+ frag_color = pow(diff, vec4(texture_gamma, texture_gamma, texture_gamma, 1.0f));
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
index bced4a5577..91a96977f0 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
@@ -31,8 +31,12 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
+#if !DEPTH_CLAMP
VARYING float pos_zd2;
+#endif
+
VARYING float pos_w;
+
VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -56,5 +60,7 @@ void main()
frag_color = vec4(1,1,1,1);
+#if !DEPTH_CLAMP
gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
index c1f2d90712..11411a605c 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
@@ -31,8 +31,12 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
+#if !DEPTH_CLAMP
VARYING float pos_zd2;
+#endif
+
VARYING float pos_w;
+
VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -45,10 +49,16 @@ void main()
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 !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();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
index 6195e2f1ec..ef153dfc5b 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -27,7 +27,9 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
uniform vec3 box_center;
uniform vec3 box_size;
@@ -37,8 +39,12 @@ void main()
//transform vertex
vec3 p = position*box_size+box_center;
vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
-
+
+#if !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/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index 7e55fdc12a..3d1b182875 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
@@ -29,11 +29,16 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
void main()
{
frag_color = vec4(1,1,1,1);
+#if !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/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
index 8b46e81f90..cc77a4cea0 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
@@ -27,14 +27,20 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#if !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/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index faa54a316e..22f4729e2e 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -61,6 +61,6 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0,0,1,0);
+ frag_data[2] = vec4(0.5,0.5,0.0,1.0); //1.0 in norm.w masks off fog
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 89448e2167..08583ad0f2 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -60,6 +60,7 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float global_gamma;
uniform float scene_light_strength;
uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
@@ -77,6 +78,34 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy*2.0;
@@ -116,7 +145,6 @@ vec3 getAtmosAttenuation()
return vary_AtmosAttenuation;
}
-
void setPositionEye(vec3 v)
{
vary_PositionEye = v;
@@ -237,6 +265,15 @@ vec3 atmosTransport(vec3 light) {
light += getAdditiveColor() * 2.0;
return light;
}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ float brightness = dot(light.rgb, vec3(0.33333));
+
+ return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+
+
vec3 atmosGetDiffuseSunlightColor()
{
return getSunlitColor();
@@ -271,57 +308,88 @@ vec3 scaleSoftClip(vec3 light)
return light;
}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
+
void main()
{
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec3 pos = getPosition_d(tc, depth).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+ vec4 norm = texture2DRect(normalMap, tc);
+ float envIntensity = norm.z;
+ norm.xyz = decode_normal(norm.xy); // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
-
+ da = pow(da, 1.0/1.3);
+
vec4 diffuse = texture2DRect(diffuseRect, tc);
+
+ //convert to gamma space
+ diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2));
+
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
vec3 col;
float bloom = 0.0;
- if (diffuse.a < 0.9)
{
calcAtmospherics(pos.xyz, 1.0);
col = atmosAmbient(vec3(0));
- col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb *= ambient;
+
+ col += atmosAffectDirectionalLight(max(min(da, 1.0), 0.0));
col *= diffuse.rgb;
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
if (spec.a > 0.0) // specular reflection
{
// the old infinite-sky shiny reflection
//
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r);
+ vec3 dumbshiny = vary_SunlitColor*(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) / 4;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
col += spec_contrib;
-
- //add environmentmap
+ }
+
+
+ col = mix(col.rgb, diffuse.rgb, diffuse.a);
+
+ if (envIntensity > 0.0)
+ { //add environmentmap
vec3 env_vec = env_mat * refnormpersp;
- col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,
- max(spec.a-diffuse.a*2.0, 0.0));
+
+
+ vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+
+ col = mix(col.rgb, refcol,
+ envIntensity);
+ }
+
+ if (norm.w < 0.5)
+ {
+ col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
+ col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
}
-
- col = atmosLighting(col);
- col = scaleSoftClip(col);
- col = mix(col.rgb, diffuse.rgb, diffuse.a);
- }
- else
- {
- col = diffuse.rgb;
+ col = pow(col, vec3(2.2));
+
+ //col = vec3(1,0,1);
+ //col.g = envIntensity;
}
frag_color.rgb = col;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
index c6031fc45a..b59fcbe017 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
@@ -35,6 +35,6 @@ 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;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index cca63872de..1975b18652 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -22,18 +22,15 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+#extension GL_ARB_texture_rectangle : enable
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
-//class 1 -- no shadows
-
-#extension GL_ARB_texture_rectangle : enable
-
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
@@ -41,6 +38,7 @@ uniform sampler2DRect normalMap;
uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -57,20 +55,59 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
+uniform float size;
uniform vec3 color;
uniform float falloff;
-uniform float size;
-VARYING vec4 vary_fragcoord;
VARYING vec3 trans_center;
-
+VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(pow(col.rgb, vec3(2.2)), col.a);
+}
+
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
@@ -86,6 +123,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -103,6 +141,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
@@ -136,15 +175,17 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
+
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0, norm.z);
+ float envIntensity = norm.z;
+ norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -158,7 +199,10 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 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;
+
if (dist_atten <= 0.0)
{
discard;
@@ -172,31 +216,35 @@ void main()
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
+ vec3 dlit = vec3(0, 0, 0);
+
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
proj_tc.y < 1.0 &&
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
- float lit = 0.0;
float amb_da = proj_ambiance;
+ float lit = 0.0;
if (da > 0.0)
{
+ lit = da * dist_atten * noise;
+
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- vec3 lcol = color.rgb * plcol.rgb * plcol.a;
+ dlit = color.rgb * plcol.rgb * plcol.a;
- lit = da * dist_atten * noise;
-
- col = lcol*lit*diff_tex;
- amb_da += (da*0.5)*proj_ambiance;
+ col = dlit*lit*diff_tex;
+ //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);
@@ -205,14 +253,38 @@ void main()
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;
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;
}
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+
if (spec.a > 0.0)
{
+ 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)
+ {
+
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb;
+ //col += spec.rgb;
+ }
+ }
+
+
+ if (envIntensity > 0.0)
+ {
vec3 ref = reflect(normalize(pos), norm);
//project from point pos in direction ref to plane proj_p, proj_n
@@ -229,8 +301,9 @@ void main()
{
stc.xy /= stc.w;
- float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+ float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
+ //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
@@ -238,8 +311,7 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
+ col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;
}
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
index bac74cbbef..6653f57ee1 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -49,6 +49,40 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -123,7 +157,7 @@ void main()
vec4 pos = getPosition(pos_screen);
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+ norm = decode_normal(norm.xy);
frag_color[0] = 1.0;
frag_color[1] = calcAmbientOcclusion(pos, norm);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index daf1cc7ea2..52a429465f 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -39,6 +39,12 @@ VARYING vec3 vary_normal;
VARYING vec4 vary_texcoord0;
VARYING vec4 vary_texcoord1;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
@@ -56,6 +62,6 @@ void main()
frag_data[0] = vec4(outColor.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index da253846ef..808750496f 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -37,6 +37,12 @@ VARYING vec2 vary_texcoord0;
uniform float minimum_alpha;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -48,5 +54,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(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index 1ae006bc8a..daa2fb390a 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -67,6 +67,12 @@ VARYING vec4 littleWave;
VARYING vec4 view;
VARYING vec4 vary_position;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 color;
@@ -161,5 +167,5 @@ void main()
frag_data[0] = vec4(color.rgb, 0.5); // diffuse
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
- frag_data[2] = vec4(screenspacewavef.xyz*0.5+0.5, screenspacewavef.z*0.5); // normalxyz, displace
+ frag_data[2] = vec4(encode_normal(screenspacewavef), 0.0, 0.0); // normalxyz, displace
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index 5aff156eae..352cea7aaa 100755
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -82,7 +82,8 @@ void main()
pos.w = 1.0;
pos = modelview_matrix*pos;
- calcAtmospherics(view.xyz);
+ calcAtmospherics(pos.xyz);
+
//pass wave parameters to pixel shader
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
new file mode 100644
index 0000000000..6523a06d22
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
@@ -0,0 +1,67 @@
+/**
+ * @file debugF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D depthMap;
+
+uniform float delta;
+
+VARYING vec2 tc0;
+VARYING vec2 tc1;
+VARYING vec2 tc2;
+VARYING vec2 tc3;
+VARYING vec2 tc4;
+VARYING vec2 tc5;
+VARYING vec2 tc6;
+VARYING vec2 tc7;
+VARYING vec2 tc8;
+
+void main()
+{
+ vec4 depth1 =
+ vec4(texture2D(depthMap, tc0).r,
+ texture2D(depthMap, tc1).r,
+ texture2D(depthMap, tc2).r,
+ texture2D(depthMap, tc3).r);
+
+ vec4 depth2 =
+ vec4(texture2D(depthMap, tc4).r,
+ texture2D(depthMap, tc5).r,
+ texture2D(depthMap, tc6).r,
+ texture2D(depthMap, tc7).r);
+
+ depth1 = min(depth1, depth2);
+ float depth = min(depth1.x, depth1.y);
+ depth = min(depth, depth1.z);
+ depth = min(depth, depth1.w);
+ depth = min(depth, texture2D(depthMap, tc8).r);
+
+ gl_FragDepth = depth;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
new file mode 100644
index 0000000000..0e5dc08183
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
@@ -0,0 +1,69 @@
+/**
+ * @file debugF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&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_texture_rectangle : enable
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect depthMap;
+
+uniform float delta;
+
+VARYING vec2 tc0;
+VARYING vec2 tc1;
+VARYING vec2 tc2;
+VARYING vec2 tc3;
+VARYING vec2 tc4;
+VARYING vec2 tc5;
+VARYING vec2 tc6;
+VARYING vec2 tc7;
+VARYING vec2 tc8;
+
+void main()
+{
+ vec4 depth1 =
+ vec4(texture2DRect(depthMap, tc0).r,
+ texture2DRect(depthMap, tc1).r,
+ texture2DRect(depthMap, tc2).r,
+ texture2DRect(depthMap, tc3).r);
+
+ vec4 depth2 =
+ vec4(texture2DRect(depthMap, tc4).r,
+ texture2DRect(depthMap, tc5).r,
+ texture2DRect(depthMap, tc6).r,
+ texture2DRect(depthMap, tc7).r);
+
+ depth1 = min(depth1, depth2);
+ float depth = min(depth1.x, depth1.y);
+ depth = min(depth, depth1.z);
+ depth = min(depth, depth1.w);
+ depth = min(depth, texture2DRect(depthMap, tc8).r);
+
+ gl_FragDepth = depth;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl
new file mode 100644
index 0000000000..71d80911d6
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl
@@ -0,0 +1,59 @@
+/**
+ * @file debugV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&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;
+
+ATTRIBUTE vec3 position;
+
+uniform vec2 screen_res;
+
+uniform vec2 delta;
+
+VARYING vec2 tc0;
+VARYING vec2 tc1;
+VARYING vec2 tc2;
+VARYING vec2 tc3;
+VARYING vec2 tc4;
+VARYING vec2 tc5;
+VARYING vec2 tc6;
+VARYING vec2 tc7;
+VARYING vec2 tc8;
+
+void main()
+{
+ gl_Position = vec4(position, 1.0);
+
+ vec2 tc = (position.xy*0.5+0.5)*screen_res;
+ tc0 = tc+vec2(-delta.x,-delta.y);
+ tc1 = tc+vec2(0,-delta.y);
+ tc2 = tc+vec2(delta.x,-delta.y);
+ tc3 = tc+vec2(-delta.x,0);
+ tc4 = tc+vec2(0,0);
+ tc5 = tc+vec2(delta.x,0);
+ tc6 = tc+vec2(-delta.x,delta.y);
+ tc7 = tc+vec2(0,delta.y);
+ tc8 = tc+vec2(delta.x,delta.y);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl
new file mode 100644
index 0000000000..947c2b0065
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl
@@ -0,0 +1,42 @@
+/**
+ * @file highlightV.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;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl
new file mode 100644
index 0000000000..c5d102b739
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl
@@ -0,0 +1,42 @@
+/**
+ * @file highlightV.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;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
index cf29939cb2..eaaa7b208d 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
@@ -39,13 +39,15 @@ VARYING vec2 vary_texcoord0;
void default_lighting()
{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
+ color.rgb *= vertex_color.rgb;
+
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
index 4070d41f47..b9ddbc8e1c 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
@@ -41,13 +41,15 @@ VARYING vec2 vary_texcoord0;
void default_lighting()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
+ color.rgb *= vertex_color.rgb;
+
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
index 6c34643aab..5740987ab1 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
@@ -30,6 +30,7 @@ out vec4 frag_color;
#endif
uniform float minimum_alpha;
+uniform float texture_gamma;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -39,13 +40,16 @@ VARYING vec2 vary_texcoord0;
void fullbright_lighting()
{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
+ color.rgb *= vertex_color.rgb;
+
+ color.rgb = pow(color.rgb, vec3(texture_gamma));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
index 2ff7f795b0..c8771a3f1e 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
@@ -32,6 +32,8 @@ out vec4 frag_color;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+uniform float texture_gamma;
+
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -39,10 +41,14 @@ void fullbright_lighting()
{
vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ color.rgb = pow(color.rgb, vec3(texture_gamma));
+
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
+ color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
+
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
index f4477bd29a..f72f20b03d 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
@@ -30,6 +30,7 @@ out vec4 frag_color;
#endif
uniform float minimum_alpha;
+uniform float texture_gamma;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -41,17 +42,22 @@ VARYING vec2 vary_texcoord0;
void fullbright_lighting()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
+
+ color.rgb *= vertex_color.rgb;
+ color.rgb = pow(color.rgb, vec3(texture_gamma));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
+ color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
+
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
index 777c8b45bb..c8282e9a51 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
@@ -50,7 +50,7 @@ void fullbright_shiny_lighting()
color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
index 4fa3b1d939..e7dbd4bbd2 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
@@ -51,7 +51,7 @@ void fullbright_shiny_lighting()
color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
index 58984a4263..5886fc65be 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
@@ -48,7 +48,7 @@ void fullbright_shiny_lighting_water()
color.rgb = fullbrightShinyAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = applyWaterFog(color);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
index a39b7205d7..cddc7d8df8 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
@@ -49,7 +49,7 @@ void fullbright_shiny_lighting_water()
color.rgb = fullbrightShinyAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = applyWaterFog(color);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
index 9c82056fd7..6dd3bb937f 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
@@ -41,7 +41,9 @@ VARYING vec2 vary_texcoord0;
void fullbright_lighting_water()
{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+
+ color.rgb *= vertex_color.rgb;
if (color.a < minimum_alpha)
{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
index 52e3b2ad02..9208c148ef 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
@@ -50,7 +50,7 @@ void shiny_lighting()
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
index 474d5ea496..92628faa68 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
@@ -51,7 +51,7 @@ void shiny_lighting()
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
index d2a4c47aac..61841674e2 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
@@ -47,7 +47,7 @@ void shiny_lighting_water()
color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
color.rgb = atmosLighting(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = applyWaterFog(color);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
index f3bd662364..0b6e835fd0 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
@@ -48,7 +48,7 @@ void shiny_lighting_water()
color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
color.rgb = atmosLighting(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = applyWaterFog(color);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
index b68240ba0d..3426fea52f 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
@@ -39,7 +39,9 @@ VARYING vec2 vary_texcoord0;
void default_lighting_water()
{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+
+ color.rgb *= vertex_color.rgb;
if (color.a < minimum_alpha)
{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
index da3b20012d..d9faa9b314 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
@@ -41,7 +41,9 @@ VARYING vec2 vary_texcoord0;
void default_lighting_water()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
+
+ color.rgb *= vertex_color.rgb;
if (color.a < minimum_alpha)
{
diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
index 8494ffba52..9064904191 100755
--- a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
@@ -48,11 +48,9 @@ void main()
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+ vertex_color = emissive;
+
calcAtmospherics(pos.xyz);
- vertex_color = emissive;
-
gl_Position = projection_matrix*vec4(pos, 1.0);
-
-
}
diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
index 44f1aa34a0..449d8d8b4e 100755
--- a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
+++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
@@ -25,12 +25,12 @@
uniform mat3 normal_matrix;
-ATTRIBUTE vec3 binormal;
+ATTRIBUTE vec4 tangent;
-VARYING vec4 binormal_out;
+VARYING vec4 tangent_out;
void main()
{
- binormal_out = vec4(normal_matrix * binormal, 0.0);
+ tangent_out = vec4(normal_matrix * tangent.xyz), tangent.w);
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
deleted file mode 100755
index 12706f130b..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * @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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-uniform sampler2DRect depthMap;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform vec2 screen_res;
-uniform vec2 shadow_res;
-
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-
-uniform float shadow_bias;
-
-uniform mat4 inv_proj;
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
- return shadow*0.2;
-}
-
-
-void main()
-{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- float shadow = 0.0;
- vec4 pos = vec4(vary_position, 1.0);
-
- vec4 spos = pos;
-
- if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos)*w;
- weight += w;
- }
-
-
- shadow /= weight;
- }
- else
- {
- shadow = 1.0;
- }
-
- vec4 diff = diffuseLookup(vary_texcoord0.xy);
-
- vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
- vec4 color = diff * col;
-
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
-
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
index 228dc104ac..9670d59399 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
@@ -52,12 +52,54 @@ VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
VARYING vec4 vertex_color;
+VARYING vec3 vary_norm;
uniform vec2 shadow_res;
uniform float shadow_bias;
uniform mat4 inv_proj;
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+vec3 calcDirectionalLight(vec3 n, vec3 l)
+{
+ float a = pow(max(dot(n,l),0.0), 0.7);
+ return vec3(a,a,a);
+}
+
+vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+{
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float d = dot(lv,lv);
+
+ float da = 0.0;
+
+ if (d > 0.0 && la > 0.0 && fa > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist2 = d/la;
+ da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= max(pow(dot(n, lv), 0.7), 0.0);
+ }
+
+ return vec3(da,da,da);
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
@@ -161,17 +203,32 @@ void main()
{
shadow = 1.0;
}
-
+ vec3 n = vary_norm;
+ vec3 l = light_position[0].xyz;
+ vec3 dlight = calcDirectionalLight(n, l);
+ dlight = dlight * vary_directional.rgb * vary_pointlight_col;
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
- vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
+ vec4 col = vec4(vary_ambient + dlight*shadow, vertex_color.a);
vec4 color = diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
+ vec3 light_col = vec3(0,0,0);
+
+ #define LIGHT_LOOP(i) \
+ light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
+ color.rgb += diff.rgb * vary_pointlight_col * light_col;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
index c3950a10e1..fae279fba0 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
@@ -53,6 +53,7 @@ VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
uniform vec2 shadow_res;
@@ -60,6 +61,47 @@ uniform float shadow_bias;
uniform mat4 inv_proj;
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+vec3 calcDirectionalLight(vec3 n, vec3 l)
+{
+ float a = pow(max(dot(n,l),0.0), 0.7);
+ return vec3(a, a, a);
+}
+
+vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+{
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float d = dot(lv,lv);
+
+ float da = 0.0;
+
+ if (d > 0.0 && la > 0.0 && fa > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist2 = d/la;
+ da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= max(pow(dot(n, lv), 0.7), 0.0);
+ }
+
+ return vec3(da,da,da);
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
@@ -169,15 +211,31 @@ void main()
{
shadow = 1.0;
}
+ vec3 n = vary_norm;
+ vec3 l = light_position[0].xyz;
+ vec3 dlight = calcDirectionalLight(n, l);
+ dlight = dlight * vary_directional.rgb * vary_pointlight_col;
- vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0);
+ vec4 col = vec4(vary_ambient + dlight*shadow, 1.0);
vec4 color = diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
+ vec3 light_col = vec3(0,0,0);
+
+ #define LIGHT_LOOP(i) \
+ light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
+ color.rgb += diff.rgb * vary_pointlight_col * light_col;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
index 9629cfe824..7f4d82ecc6 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
@@ -50,7 +50,7 @@ VARYING vec3 vary_pointlight_col;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-
+VARYING vec3 vary_norm;
uniform float near_clip;
uniform float shadow_offset;
@@ -115,7 +115,8 @@ void main()
n.xyz = normalize(n.xyz-pos.xyz);
vec3 norm = n.xyz;
-
+ vary_norm = norm;
+
float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
index 1586aab0f2..13c6ffc607 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
@@ -25,19 +25,36 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
+uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
+
+#ifdef USE_INDEXED_TEX
void passTextureIndex();
+#endif
+
ATTRIBUTE vec3 normal;
+
+#ifdef USE_VERTEX_COLOR
ATTRIBUTE vec4 diffuse_color;
+#endif
+
ATTRIBUTE vec2 texcoord0;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+#else
+#ifdef IS_AVATAR_SKIN
+mat4 getSkinnedTransform();
+#endif
+#endif
+
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
-float calcDirectionalLight(vec3 n, vec3 l);
+vec3 calcDirectionalLight(vec3 n, vec3 l);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@@ -50,9 +67,12 @@ VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
+#ifdef USE_VERTEX_COLOR
VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+#endif
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
uniform float near_clip;
uniform float shadow_offset;
@@ -63,13 +83,15 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
-float calcDirectionalLight(vec3 n, vec3 l)
+uniform vec3 sun_dir;
+
+vec3 calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
- return a;
+ return vec3(a,a,a);
}
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
@@ -96,55 +118,107 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= max(dot(n, lv), 0.0);
}
- return da;
+ return vec3(da,da,da);
}
void main()
{
+ vec4 pos;
+ vec3 norm;
+
//transform vertex
+#ifdef HAS_SKIN
+ mat4 trans = getObjectSkinnedTransform();
+ trans = modelview_matrix * trans;
+
+ pos = trans * vec4(position.xyz, 1.0);
+
+ norm = position.xyz + normal.xyz;
+ norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz);
+ vec4 frag_pos = projection_matrix * pos;
+ gl_Position = frag_pos;
+#else
+
+#ifdef IS_AVATAR_SKIN
+ mat4 trans = getSkinnedTransform();
+ vec4 pos_in = vec4(position.xyz, 1.0);
+ pos.x = dot(trans[0], pos_in);
+ pos.y = dot(trans[1], pos_in);
+ pos.z = dot(trans[2], pos_in);
+ pos.w = 1.0;
+
+ norm.x = dot(trans[0].xyz, normal);
+ norm.y = dot(trans[1].xyz, normal);
+ norm.z = dot(trans[2].xyz, normal);
+ norm = normalize(norm);
+
+ vec4 frag_pos = projection_matrix * pos;
+ gl_Position = frag_pos;
+#else
+ norm = normalize(normal_matrix * normal);
vec4 vert = vec4(position.xyz, 1.0);
- passTextureIndex();
- vec4 pos = (modelview_matrix * vert);
+ pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#endif
+#endif
+
+#ifdef USE_INDEXED_TEX
+ passTextureIndex();
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vec3 norm = normalize(normal_matrix * normal);
+#else
+ vary_texcoord0 = texcoord0;
+#endif
+ vary_norm = norm;
float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
-
+
calcAtmospherics(pos.xyz);
+#ifndef USE_VERTEX_COLOR
+ vec4 diffuse_color = vec4(1,1,1,1);
+#endif
+
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
+ vec3 dff = pow(diffuse_color.rgb, vec3(2.2f,2.2f,2.2f));
- vary_pointlight_col = col.rgb*diffuse_color.rgb;
+ vary_pointlight_col = dff;
col.rgb = vec3(0,0,0);
// Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
+ col.rgb = atmosAmbient(col.rgb);
- vary_ambient = col.rgb*diffuse_color.rgb;
- vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb *= ambient;
+
+ vary_directional.rgb = atmosAffectDirectionalLight(1.0f);
+ vary_ambient = col.rgb*dff;
- col.rgb = col.rgb*diffuse_color.rgb;
+ col.rgb = col.rgb*dff;
+#ifdef USE_VERTEX_COLOR
vertex_color = col;
-
-
+#endif
+#ifdef HAS_SKIN
+ vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
+#else
+
+#ifdef IS_AVATAR_SKIN
+ vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
+#else
pos = modelview_projection_matrix * vert;
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
-
+#endif
+
+#endif
+
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index 5621e47ab7..780df9ed1a 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -39,6 +39,7 @@ uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -67,10 +68,51 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(pow(col.rgb, vec3(2.2)), col.a);
+}
+
+
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
-
+ ret = correctWithGamma(ret);
+
vec2 dist = tc-vec2(0.5);
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
@@ -85,7 +127,8 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
-
+ ret = correctWithGamma(ret);
+
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
@@ -102,7 +145,8 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
-
+ ret = correctWithGamma(ret);
+
vec2 dist = tc-vec2(0.5);
float d = dot(dist,dist);
@@ -135,9 +179,9 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = center.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
@@ -154,7 +198,10 @@ void main()
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+
+ float envIntensity = norm.z;
+
+ norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -168,7 +215,9 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 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;
if (dist_atten <= 0.0)
{
discard;
@@ -177,11 +226,15 @@ void main()
lv = proj_origin-pos.xyz;
lv = normalize(lv);
float da = dot(norm, lv);
-
+
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
+
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+ vec3 dlit = vec3(0, 0, 0);
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -189,21 +242,21 @@ void main()
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
- float lit = 0.0;
float amb_da = proj_ambiance;
-
+ float lit = 0.0;
+
if (da > 0.0)
{
+ lit = da * dist_atten * noise;
+
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
- vec3 lcol = color.rgb * plcol.rgb * plcol.a;
+ dlit = color.rgb * plcol.rgb * plcol.a;
- lit = da * dist_atten * noise;
-
- col = lcol*lit*diff_tex*shadow;
+ col = dlit*lit*diff_tex*shadow;
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
@@ -219,10 +272,37 @@ void main()
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+
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));
+
+ 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 (envIntensity > 0.0)
+ {
vec3 ref = reflect(normalize(pos), norm);
//project from point pos in direction ref to plane proj_p, proj_n
@@ -239,8 +319,9 @@ void main()
{
stc.xy /= stc.w;
- float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+ float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
+ //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
@@ -248,8 +329,7 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
+ col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;
}
}
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 9df9d75905..67bac1f7c2 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -38,7 +38,6 @@ uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
uniform sampler2D lightFunc;
-uniform vec3 gi_quad;
uniform float blur_size;
uniform float blur_fidelity;
@@ -60,16 +59,13 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float global_gamma;
uniform float scene_light_strength;
uniform mat3 env_mat;
uniform vec4 shadow_clip;
uniform mat3 ssao_effect_mat;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
uniform vec3 sun_dir;
-
VARYING vec2 vary_fragcoord;
vec3 vary_PositionEye;
@@ -79,6 +75,43 @@ vec3 vary_AmblitColor;
vec3 vary_AdditiveColor;
vec3 vary_AtmosAttenuation;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy*2.0;
@@ -118,7 +151,6 @@ vec3 getAtmosAttenuation()
return vary_AtmosAttenuation;
}
-
void setPositionEye(vec3 v)
{
vary_PositionEye = v;
@@ -222,6 +254,10 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
+ tmpAmbient)));
//brightness of surface both sunlight and ambient
+ /*setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma);
+ setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma);
+ setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);*/
+
setSunlitColor(vec3(sunlight * .5));
setAmblitColor(vec3(tmpAmbient * .25));
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
@@ -239,6 +275,15 @@ vec3 atmosTransport(vec3 light) {
light += getAdditiveColor() * 2.0;
return light;
}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ float brightness = dot(light.rgb, vec3(0.33333));
+
+ return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+
+
vec3 atmosGetDiffuseSunlightColor()
{
return getSunlitColor();
@@ -273,65 +318,103 @@ vec3 scaleSoftClip(vec3 light)
return light;
}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
+
void main()
{
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec3 pos = getPosition_d(tc, depth).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+ vec4 norm = texture2DRect(normalMap, tc);
+ float envIntensity = norm.z;
+ norm.xyz = decode_normal(norm.xy); // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
-
+
+ float light_gamma = 1.0/1.3;
+ da = pow(da, light_gamma);
+
+
vec4 diffuse = texture2DRect(diffuseRect, tc);
+ //convert to gamma space
+ diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2));
+
vec3 col;
float bloom = 0.0;
-
- if (diffuse.a < 0.9)
{
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
+
float scol = max(scol_ambocc.r, diffuse.a);
+
+
+
float ambocc = scol_ambocc.g;
calcAtmospherics(pos.xyz, ambocc);
col = atmosAmbient(vec3(0));
- col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb *= ambient;
+
+ col += atmosAffectDirectionalLight(max(min(da, scol), 0.0));
col *= diffuse.rgb;
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
if (spec.a > 0.0) // specular reflection
{
// the old infinite-sky shiny reflection
//
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r);
-
+ vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(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) / 4;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
col += spec_contrib;
+ }
+
+
+ col = mix(col, diffuse.rgb, diffuse.a);
- //add environmentmap
+ if (envIntensity > 0.0)
+ { //add environmentmap
vec3 env_vec = env_mat * refnormpersp;
- col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,
- max(spec.a-diffuse.a*2.0, 0.0));
- }
- col = atmosLighting(col);
- col = scaleSoftClip(col);
+ vec3 refcol = textureCube(environmentMap, env_vec).rgb;
- col = mix(col, diffuse.rgb, diffuse.a);
- }
- else
- {
- col = diffuse.rgb;
+ col = mix(col.rgb, refcol,
+ envIntensity);
+
+ }
+
+ if (norm.w < 0.5)
+ {
+ col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
+ col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+ }
+
+ col = pow(col, vec3(2.2));
+
+ //col = vec3(1,0,1);
+ //col.g = envIntensity;
}
-
+
frag_color.rgb = col;
frag_color.a = bloom;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 6d6ad6d565..fc0e6b2388 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -39,6 +39,7 @@ uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -67,9 +68,49 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(pow(col.rgb, vec3(2.2)), col.a);
+}
+
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
@@ -85,6 +126,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -102,6 +144,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
@@ -135,9 +178,9 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
@@ -154,7 +197,8 @@ void main()
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+ float envIntensity = norm.z;
+ norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -168,7 +212,10 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 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;
+
if (dist_atten <= 0.0)
{
discard;
@@ -182,6 +229,10 @@ void main()
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+ vec3 dlit = vec3(0, 0, 0);
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -189,21 +240,21 @@ void main()
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
- float lit = 0.0;
float amb_da = proj_ambiance;
+ float lit = 0.0;
if (da > 0.0)
{
+ lit = da * dist_atten * noise;
+
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
- vec3 lcol = color.rgb * plcol.rgb * plcol.a;
-
- lit = da * dist_atten * noise;
+ dlit = color.rgb * plcol.rgb * plcol.a;
- col = lcol*lit*diff_tex*shadow;
+ col = dlit*lit*diff_tex*shadow;
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
@@ -219,10 +270,37 @@ void main()
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+
if (spec.a > 0.0)
{
+ 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)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb*shadow;
+ //col += spec.rgb;
+ }
+ }
+
+
+
+
+
+ if (envIntensity > 0.0)
+ {
vec3 ref = reflect(normalize(pos), norm);
//project from point pos in direction ref to plane proj_p, proj_n
@@ -239,8 +317,9 @@ void main()
{
stc.xy /= stc.w;
- float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+ float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
+ //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
@@ -248,8 +327,7 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
+ col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;
}
}
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 890486c4b1..7b09dd29dd 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -65,6 +65,40 @@ uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -125,11 +159,9 @@ void main()
vec4 pos = getPosition(pos_screen);
- vec4 nmap4 = texture2DRect(normalMap, pos_screen);
- nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm
- float displace = nmap4.w;
- vec3 norm = nmap4.xyz;
-
+ vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
+ norm = decode_normal(norm.xy); // unpack norm
+
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
{
frag_color = vec4(0.0); // doesn't matter
@@ -138,8 +170,8 @@ void main()
float shadow = 0.0;
float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
- vec3 shadow_pos = pos.xyz + displace*norm;
+
+ vec3 shadow_pos = pos.xyz;
vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 2dcd3d656f..01e34ed792 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -66,6 +66,40 @@ uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+ vec2 sn;
+ sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+ return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec3 n;
+ n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+ n.z = sqrt(1.0f - dot(n.xy,n.xy));
+ return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+#endif
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -186,11 +220,9 @@ void main()
vec4 pos = getPosition(pos_screen);
- vec4 nmap4 = texture2DRect(normalMap, pos_screen);
- nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm
- float displace = nmap4.w;
- vec3 norm = nmap4.xyz;
-
+ vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
+ norm = decode_normal(norm.xy); // unpack norm
+
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
{
frag_color = vec4(0.0); // doesn't matter
@@ -199,8 +231,8 @@ void main()
float shadow = 0.0;
float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
- vec3 shadow_pos = pos.xyz + displace*norm;
+
+ vec3 shadow_pos = pos.xyz;
vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
index da3d922017..d174805cc0 100755
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
@@ -129,7 +129,7 @@ void calcAtmospherics(vec3 inPositionEye) {
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+ (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+ tmpAmbient)));
-
+
//brightness of surface both sunlight and ambient
setSunlitColor(vec3(sunlight * .5));
setAmblitColor(vec3(tmpAmbient * .25));
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index d2ee09bcb5..e28bb6969a 100755
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -1084,8 +1084,7 @@
scale="0 0 .5" />
</param_skeleton>
</param>
-
- <param
+ <param
id="11001"
group="0"
name="Hover"
@@ -12308,7 +12307,7 @@ render_pass="bump">
<param_driver />
</param>
- <param
+ <param
id="11000"
group="0"
name="AppearanceMessage_Version"
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index 4c39014c8b..c64e11929d 100755
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -32,20 +32,20 @@
// 1 - We claim to support this card.
//
-3Dfx .*3Dfx.* 0 0 0 0
-3Dlabs .*3Dlabs.* 0 0 0 0
-ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0
-ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0
-ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0
-ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0
+3Dfx .*3Dfx.* 0 0 0 0
+3Dlabs .*3Dlabs.* 0 0 0 0
+ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0
+ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0
+ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0
+ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0
ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 0 0
-ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3
-ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0
-ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1
-ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0
-ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0
-ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0
-ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0
+ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3
+ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0
+ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1
+ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0
+ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0
+ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0
+ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0
ATI ASUS ARES .*ATI.*ASUS.*ARES.* 3 1 0 0
ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 0 0
ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 1 3.3
@@ -79,30 +79,30 @@ ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 2 1 1 2.1
ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 0 0
ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 2 1 1 2.1
ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 1 2.1
-ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1
+ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1
ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 1 1 1 2.1
ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 1 1 1 2.1
ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1 1 2.1
ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 0 1 1 2.1
ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 1 1 1 2.1
-ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1
-ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1
-ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3
-ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2
+ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1
+ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1
+ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3
+ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2
ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 0 0
-ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0
-ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0
-ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2
+ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0
+ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0
+ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2
ATI FireMV .*ATI.*FireMV.* 0 1 1 1.3
-ATI Generic .*ATI.*Generic.* 0 0 0 0
-ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 0 0
+ATI Generic .*ATI.*Generic.* 0 0 0 0
+ATI Hercules 9800 .*ATI.*Hercules.* 9800.* 1 1 0 0
ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 0 0
-ATI M52 .*ATI.*M52.* 1 1 0 0
-ATI M54 .*ATI.*M54.* 1 1 0 0
-ATI M56 .*ATI.*M56.* 1 1 0 0
-ATI M71 .*ATI.*M71.* 1 1 0 0
-ATI M72 .*ATI.*M72.* 1 1 0 0
-ATI M76 .*ATI.*M76.* 3 1 0 0
+ATI M52 .*ATI.*M52.* 1 1 0 0
+ATI M54 .*ATI.*M54.* 1 1 0 0
+ATI M56 .*ATI.*M56.* 1 1 0 0
+ATI M71 .*ATI.*M71.* 1 1 0 0
+ATI M72 .*ATI.*M72.* 1 1 0 0
+ATI M76 .*ATI.*M76.* 3 1 0 0
ATI Radeon HD 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 2 1 1 4.2
ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 2 1 1 4.2
ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1 1 4.2
@@ -124,12 +124,12 @@ ATI ASUS HD7600 .*ATI.*ASUS.* HD76.* 3 1 0 0
ATI ASUS HD7700 .*ATI.*ASUS.* HD77.* 4 1 1 4.2
ATI ASUS HD7800 .*ATI.*ASUS.* HD78.* 5 1 1 4.2
ATI ASUS HD7900 .*ATI.*ASUS.* HD79.* 5 1 1 4.2
-ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1 1 3.3
-ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3
-ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0
-ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1 0 0
-ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 0 1 1 2.1
-ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 1 1 1 2.1
+ATI Mobility Radeon 4100 .*ATI.*Mobility.* 41.. 1 1 1 3.3
+ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3
+ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0
+ATI Mobility Radeon 9800 .*ATI.*Mobility.* 98.* 1 1 0 0
+ATI Mobility Radeon 9700 .*ATI.*Mobility.* 97.* 0 1 1 2.1
+ATI Mobility Radeon 9600 .*ATI.*Mobility.* 96.* 1 1 1 2.1
ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD *530v.* 1 1 1 3.3
ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD *540v.* 1 1 1 3.3
ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD *545v.* 2 1 1 4
@@ -176,7 +176,7 @@ ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 1 1 1 4
ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1 0 0
ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1 1 3.3
ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1 0 0
-ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3
+ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3
ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1 1 4
ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1 0 0
ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1 1 4
@@ -202,128 +202,128 @@ ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1 1 4.2
ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1 1 4.2
ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 4 1 1 4.2
ATI Radeon HD 6900 .*ATI.*Radeon HD *69.. 5 1 1 4.2
-ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0
-ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1
-ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4
-ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3
-ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0
-ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2
-ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0
-ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3
-ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0
-ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3
-ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1
-ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1
-ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0
-ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1
-ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0
-ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0
-ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0
+ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0
+ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1
+ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4
+ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3
+ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0
+ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2
+ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0
+ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3
+ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0
+ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3
+ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1
+ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1
+ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0
+ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1
+ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0
+ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0
+ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0
ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 0 0
-ATI RS880M .*ATI.*RS880M 1 1 0 0
-ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0
-ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0
+ATI RS880M .*ATI.*RS880M 1 1 0 0
+ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0
+ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0
ATI Radeon X300 .*ATI.*Radeon *X3.* 1 1 1 2.1
-ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0
-ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1
+ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0
+ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1
ATI Radeon X600 .*ATI.*Radeon ?X6.* 1 1 1 2.1
-ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1
-ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1
-ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0
-ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1
-ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0
-ATI R300 (9700) .*R300.* 0 1 1 2.1
-ATI R350 (9800) .*R350.* 1 1 0 0
-ATI R580 (X1900) .*R580.* 3 1 0 0
-ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0
-ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0
-ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0
-ATI RV350 (9600) .*RV350.* 0 1 0 0
-ATI RV370 (X300) .*RV370.* 0 1 0 0
-ATI RV410 (X700) .*RV410.* 1 1 0 0
-ATI RV515 .*RV515.* 1 1 0 0
-ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0
-ATI RV380 .*RV380.* 0 1 0 0
-ATI RV530 .*RV530.* 1 1 0 0
-ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0
-ATI RX700 .*RX700.* 1 1 0 0
-AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0
-AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1
-AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0
-AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0
+ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1
+ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1
+ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0
+ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1
+ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0
+ATI R300 (9700) .*R300.* 0 1 1 2.1
+ATI R350 (9800) .*R350.* 1 1 0 0
+ATI R580 (X1900) .*R580.* 3 1 0 0
+ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0
+ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0
+ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0
+ATI RV350 (9600) .*RV350.* 0 1 0 0
+ATI RV370 (X300) .*RV370.* 0 1 0 0
+ATI RV410 (X700) .*RV410.* 1 1 0 0
+ATI RV515 .*RV515.* 1 1 0 0
+ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0
+ATI RV380 .*RV380.* 0 1 0 0
+ATI RV530 .*RV530.* 1 1 0 0
+ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0
+ATI RX700 .*RX700.* 1 1 0 0
+AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0
+AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1
+AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0
+AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0
AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 0 0
-AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0
-AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0
-AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0
-AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0
+AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0
+AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0
+AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0
+AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0
AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 0 0
AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 0
-AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1
-AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2
-AMD RV610 (HD 2400) .*RV610.* 1 1 0 0
-AMD RV620 (HD 3400) .*RV620.* 1 1 0 0
-AMD RV630 (HD 2600) .*RV630.* 2 1 0 0
+AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1
+AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2
+AMD RV610 (HD 2400) .*RV610.* 1 1 0 0
+AMD RV620 (HD 3400) .*RV620.* 1 1 0 0
+AMD RV630 (HD 2600) .*RV630.* 2 1 0 0
AMD RV635 (HD 3600) .*RV635.* 3 1 0 0
-AMD RV670 (HD 3800) .*RV670.* 3 1 0 0
-AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0
-AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0
-AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4
+AMD RV670 (HD 3800) .*RV670.* 3 1 0 0
+AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0
+AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0
+AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4
AMD RV730 (HD 4600) .*RV730.* 3 1 0 0
-AMD RV740 (HD 4700) .*RV740.* 3 1 0 0
-AMD RV770 (HD 4800) .*RV770.* 3 1 0 0
-AMD RV790 (HD 4800) .*RV790.* 3 1 0 0
-ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3
-ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0
-ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0
+AMD RV740 (HD 4700) .*RV740.* 3 1 0 0
+AMD RV770 (HD 4800) .*RV770.* 3 1 0 0
+AMD RV790 (HD 4800) .*RV790.* 3 1 0 0
+ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3
+ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0
+ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0
ATI FirePro 2000 .*ATI.*FirePro 2.* 2 1 1 4.1
-ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0
+ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0
ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 0 0
-ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0
-ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0
-ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2
-ATI R300 (9700) .*R300.* 0 1 1 2.1
+ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0
+ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0
+ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2
+ATI R300 (9700) .*R300.* 0 1 1 2.1
ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 0 4.2
-Intel X3100 .*Intel.*X3100.* 1 1 1 2.1
-Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3
-Intel 830M .*Intel.*830M 0 0 0 0
-Intel 845G .*Intel.*845G 0 0 1 1.4
-Intel 855GM .*Intel.*855GM 0 0 1 1.4
-Intel 865G .*Intel.*865G 0 0 1 1.4
-Intel 900 .*Intel.*900.*900 0 0 0 0
-Intel 915GM .*Intel.*915GM 0 0 1 1.4
-Intel 915G .*Intel.*915G 0 0 1 1.4
-Intel 945GM .*Intel.*945GM.* 0 1 1 1.4
-Intel 945G .*Intel.*945G.* 0 1 1 1.4
-Intel 950 .*Intel.*950.* 0 1 1 1.4
-Intel 965 .*Intel.*965.* 0 1 1 2.1
-Intel G33 .*Intel.*G33.* 1 0 1 1.4
-Intel G41 .*Intel.*G41.* 1 1 1 2.1
-Intel G45 .*Intel.*G45.* 1 1 1 2.1
-Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4
-Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4
-Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3
-Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2
-Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2
-Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1
-Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4
-Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1
-Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4
+Intel X3100 .*Intel.*X3100.* 1 1 1 2.1
+Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3
+Intel 830M .*Intel.*830M 0 0 0 0
+Intel 845G .*Intel.*845G 0 0 1 1.4
+Intel 855GM .*Intel.*855GM 0 0 1 1.4
+Intel 865G .*Intel.*865G 0 0 1 1.4
+Intel 900 .*Intel.*900.*900 0 0 0 0
+Intel 915GM .*Intel.*915GM 0 0 1 1.4
+Intel 915G .*Intel.*915G 0 0 1 1.4
+Intel 945GM .*Intel.*945GM.* 0 1 1 1.4
+Intel 945G .*Intel.*945G.* 0 1 1 1.4
+Intel 950 .*Intel.*950.* 0 1 1 1.4
+Intel 965 .*Intel.*965.* 0 1 1 2.1
+Intel G33 .*Intel.*G33.* 1 0 1 1.4
+Intel G41 .*Intel.*G41.* 1 1 1 2.1
+Intel G45 .*Intel.*G45.* 1 1 1 2.1
+Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4
+Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4
+Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3
+Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2
+Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2
+Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1
+Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4
+Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1
+Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4
Intel HD2000 .*Intel.*HD2000.* 2 1 0 0
Intel HD3000 .*Intel.*HD3000.* 3 1 0 0
-Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4
-Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1
-Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1
-Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0
-Intel Montara .*Intel.*Montara.* 0 0 1 1.3
-Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4
-Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3
-Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0
-Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1
-Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1
-Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0
-Matrox .*Matrox.* 0 0 0 0
+Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4
+Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1
+Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1
+Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0
+Intel Montara .*Intel.*Montara.* 0 0 1 1.3
+Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4
+Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3
+Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0
+Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1
+Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1
+Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0
+Matrox .*Matrox.* 0 0 0 0
Mesa .*Mesa.* 1 0 1 2.1
-Gallium .*Gallium.* 1 1 1 2.1
+Gallium .*Gallium.* 1 1 1 2.1
NVIDIA G100M .*NVIDIA .*100M.* 4 1 1 3.3
NVIDIA G102M .*NVIDIA .*102M.* 1 1 1 3.3
NVIDIA G103M .*NVIDIA .*103M.* 2 1 1 3.3
@@ -380,14 +380,14 @@ NVIDIA GTX 660M .*NVIDIA .*GTX *66*M.* 5 1 0 0
NVIDIA GTX 670M .*NVIDIA .*GTX *67*M.* 5 1 1 4.2
NVIDIA GTX 680M .*NVIDIA .*GTX *68*M.* 5 1 0 0
NVIDIA GTX 690M .*NVIDIA .*GTX *69*M.* 5 1 0 0
-NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2
+NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2
NVIDIA GT 120 .*NVIDIA .*GT *12.* 2 1 0 3
NVIDIA GT 130 .*NVIDIA .*GT *13.* 2 1 0 3.3
NVIDIA GTS 150 .*NVIDIA .*GTS *15.* 2 1 0 0
-NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3
-NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3
-NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3
-NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3
+NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3
+NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3
+NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3
+NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3
NVIDIA GT 220 .*NVIDIA .*GT *22.* 2 1 1 3.3
NVIDIA GT 230 .*NVIDIA .*GT *23.* 2 1 1 3.3
NVIDIA GT 240 .*NVIDIA .*GT *24.* 4 1 1 3.3
@@ -397,12 +397,12 @@ NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 4 1 1 3.3
NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 4 1 0 3.3
NVIDIA GTX 280 .*NVIDIA .*GTX *28.* 4 1 1 3.3
NVIDIA GTX 290 .*NVIDIA .*GTX *29.* 5 1 0 3.3
-NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3
-NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3
+NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3
+NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3
NVIDIA GT 320 .*NVIDIA .*GT *32.* 3 1 0 3.3
NVIDIA GT 330 .*NVIDIA .*GT *33.* 3 1 0 3.3
NVIDIA GT 340 .*NVIDIA .*GT *34.* 3 1 0 0
-NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3
+NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3
NVIDIA GT 420 .*NVIDIA .*GT *42.* 3 1 1 4.2
NVIDIA GT 430 .*NVIDIA .*GT *43.* 3 1 1 4.2
NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 0 4.2
@@ -429,125 +429,125 @@ NVIDIA GTX 660 .*NVIDIA .*GTX *66.* 5 1 0 4.3
NVIDIA GTX 670 .*NVIDIA .*GTX *67.* 5 1 1 4.2
NVIDIA GTX 680 .*NVIDIA .*GTX *68.* 5 1 1 4.2
NVIDIA GTX 690 .*NVIDIA .*GTX *69.* 5 1 1 4.2
-NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2
-NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0
-NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0
-NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0
-NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0
-NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0
-NVIDIA GeForce .*GeForce 256.* 0 0 0 0
-NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5
+NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2
+NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0
+NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0
+NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0
+NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0
+NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0
+NVIDIA GeForce .*GeForce 256.* 0 0 0 0
+NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5
NVIDIA GeForce 3 .*GeForce ?3 ?.* 2 1 1 2.1
NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 0 0
-NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5
+NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5
NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 0 0
NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 0 0
NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 0 0
NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 0 0
-NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2
-NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1
-NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1
-NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1
-NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1
-NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1
-NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1
-NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1
-NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0
-NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1
-NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1
-NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1
-NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1
-NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1
+NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2
+NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1
+NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1
+NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1
+NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1
+NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1
+NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1
+NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1
+NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0
+NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1
+NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1
+NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1
+NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1
+NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1
NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 0 0
NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1 0 3.3
NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 0 2.1
-NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3
+NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3
NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 1 1 1 3.3
-NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3
-NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3
+NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3
+NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3
NVIDIA GeForce 8600M .*NVIDIA .*GeForce 8600M.* 2 1 1 3.3
-NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3
+NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3
NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 2 1 1 3.3
-NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0
+NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0
NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 2 1 1 3.3
-NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3
+NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3
NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1 0 0
-NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3
+NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3
NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1 0 3.1
-NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3
+NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3
NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 1 1 1 3.3
-NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3
+NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3
NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1 1 3.3
-NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3
+NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3
NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 1 1 1 3.3
-NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3
+NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3
NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 2 1 1 3.3
-NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3
+NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3
NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 0 1 1 3.3
NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 2 1 1 3.3
-NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3
-NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0
-NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1
-NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0
-NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1
-NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1
-NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1
-NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0
-NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1
-NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0
+NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3
+NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0
+NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1
+NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0
+NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1
+NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1
+NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1
+NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0
+NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1
+NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0
NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 0 0
-NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0
-NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0
-NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1
-NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5
-NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0
-NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0
-NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0
-NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1
+NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0
+NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0
+NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1
+NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5
+NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0
+NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0
+NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0
+NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1
NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 0 0
NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 1 2
-NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0
-NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1
-NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0
-NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1
+NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0
+NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1
+NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0
+NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1
NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 0 0
-NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0
-NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1
-NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1
-NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1
-NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1
-NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0
-NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1
-NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0
-NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0
-NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0
-NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0
-NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3
-NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0
-NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0
-NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0
-NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0
-NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0
+NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0
+NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1
+NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1
+NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1
+NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1
+NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0
+NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1
+NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0
+NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0
+NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0
+NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0
+NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3
+NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0
+NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0
+NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0
+NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0
+NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0
NVIDIA N10 .*NVIDIA .*N10.* 1 1 0 0
NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 0
NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 0 3
-NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0
-NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0
-NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0
-NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0
-NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0
-NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0
-NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0
-NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3
-NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0
+NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0
+NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0
+NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0
+NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0
+NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0
+NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0
+NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0
+NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3
+NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0
NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 0 0
-NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0
-NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0
-NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0
-NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0
-NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0
-NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0
-NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0
+NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0
+NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0
+NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0
+NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0
+NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0
+NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0
+NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0
NVIDIA Quadro2 .*Quadro2.* 0 1 0 0
NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 0 4.2
NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1 0 4.2
@@ -555,12 +555,12 @@ NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1 0 0
NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 0 0
NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 0 4.2
NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1 0 0
-NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1 0 0
-NVIDIA Quadro 400 .*Quadro.*400.* 2 1 0 3.3
+NVIDIA Quadro 6000 .*Quadro.* 6000.* 3 1 0 0
+NVIDIA Quadro 400 .*Quadro.* 400.* 2 1 0 3.3
NVIDIA Quadro 600 .*Quadro.*600.* 2 1 0 3.3
NVIDIA Quadro4 .*Quadro4.* 0 1 0 0
-NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0
-NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0
+NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0
+NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0
NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 0 0
NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 0 2.1
NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 0 0
@@ -574,7 +574,7 @@ NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 0 3.2
NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 0 0
NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 0 3.3
NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1 0 0
-NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3
+NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3
NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1 1 3.3
NVIDIA Quadro NVS 300M .*NVIDIA .*NVS *300M.* 2 1 0 0
NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1 0 0
@@ -583,16 +583,16 @@ NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1 0 0
NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1 0 4.1
NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1 0 0
NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 0 3.2
-NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1
+NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1
NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 0
NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 0
-S3 .*S3 Graphics.* 0 0 1 1.4
-SiS SiS.* 0 0 1 1.5
-Trident Trident.* 0 0 0 0
-Tungsten Graphics Tungsten.* 0 0 0 0
-XGI XGI.* 0 0 0 0
-VIA VIA.* 0 0 0 0
-Apple Generic Apple.*Generic.* 0 0 0 0
-Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0
-Humper Humper.* 0 1 1 2.1
-PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3
+S3 .*S3 Graphics.* 0 0 1 1.4
+SiS SiS.* 0 0 1 1.5
+Trident Trident.* 0 0 0 0
+Tungsten Graphics Tungsten.* 0 0 0 0
+XGI XGI.* 0 0 0 0
+VIA VIA.* 0 0 0 0
+Apple Generic Apple.*Generic.* 0 0 0 0
+Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0
+Humper Humper.* 0 1 1 2.1
+PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 1c27811351..d82cb4fb21 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -4321,7 +4321,7 @@ void LLAgent::sendAgentSetAppearance()
return;
}
-
+
LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
//dumpAvatarTEs( "sendAgentSetAppearance()" );
@@ -4432,7 +4432,7 @@ void LLAgent::sendAgentSetAppearance()
}
}
- //llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
+// llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
sendReliableMessage();
}
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 0896aa5972..488a134aa2 100755
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -2267,22 +2267,22 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
gFocusMgr.setKeyboardFocus( NULL );
gFocusMgr.setMouseCapture( NULL );
- // Remove any pitch or rotation from the avatar
- LLVector3 at = gAgent.getAtAxis();
- at.mV[VZ] = 0.f;
- at.normalize();
- gAgent.resetAxes(at);
-
- gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
- gAgent.setCustomAnim(TRUE);
- gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
- LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
-
- if (turn_motion)
- {
- // delay camera animation long enough to play through turn animation
- setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
- }
+ // Remove any pitch or rotation from the avatar
+ LLVector3 at = gAgent.getAtAxis();
+ at.mV[VZ] = 0.f;
+ at.normalize();
+ gAgent.resetAxes(at);
+
+ gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
+ gAgent.setCustomAnim(TRUE);
+ gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
+ LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
+
+ if (turn_motion)
+ {
+ // delay camera animation long enough to play through turn animation
+ setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
+ }
}
LLVector3 agent_at = gAgent.getAtAxis();
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index fdc2cdb78d..f92274dbbd 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -127,9 +127,9 @@
#if LL_WINDOWS
-# include <share.h> // For _SH_DENYWR in initMarkerFile
+# include <share.h> // For _SH_DENYWR in processMarkerFiles
#else
-# include <sys/file.h> // For initMarkerFile support
+# include <sys/file.h> // For processMarkerFiles
#endif
#include "llapr.h"
@@ -599,7 +599,8 @@ static void settings_to_globals()
static void settings_modify()
{
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
- LLPipeline::sRenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
LLVOAvatar::sUseImpostors = gSavedSettings.getBOOL("RenderUseImpostors");
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
@@ -741,8 +742,10 @@ bool LLAppViewer::init()
// this allows simple skinned file lookups to work
gDirUtilp->setSkinFolder("default", "en");
- initLogging();
+ initLoggingAndGetLastDuration();
+ processMarkerFiles();
+
//
// OK to write stuff to logs now, we've now crash reported if necessary
//
@@ -765,7 +768,7 @@ bool LLAppViewer::init()
logdir += gDirUtilp->getDirDelimiter();
setMiniDumpDir(logdir);
- // Although initLogging() is the right place to mess with
+ // Although initLoggingAndGetLastDuration() is the right place to mess with
// setFatalFunction(), we can't query gSavedSettings until after
// initConfiguration().
S32 rc(gSavedSettings.getS32("QAModeTermCode"));
@@ -1726,7 +1729,7 @@ bool LLAppViewer::cleanup()
gAudiop->setStreamingAudioImpl(NULL);
// shut down the audio subsystem
- gAudiop->shutdown();
+ gAudiop->shutdown();
delete gAudiop;
gAudiop = NULL;
@@ -1802,6 +1805,8 @@ bool LLAppViewer::cleanup()
LLAvatarAppearance::cleanupClass();
+ LLAvatarAppearance::cleanupClass();
+
LLPostProcess::cleanupClass();
LLTracker::cleanupInstance();
@@ -2125,7 +2130,7 @@ void errorCallback(const std::string &error_string)
LLError::crashAndLoop(error_string);
}
-void LLAppViewer::initLogging()
+void LLAppViewer::initLoggingAndGetLastDuration()
{
//
// Set up logging defaults for the viewer
@@ -2150,24 +2155,35 @@ void LLAppViewer::initLogging()
std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);
llstat start_marker_stat;
llstat log_file_stat;
- if ( 0 == LLFile::stat(start_marker_file_name, &start_marker_stat)
- && 0 == LLFile::stat(log_file, &log_file_stat)
- )
+ std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below
+ int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat);
+ int log_stat_result = LLFile::stat(log_file, &log_file_stat);
+ if ( 0 == start_stat_result && 0 == log_stat_result )
{
int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;
// only report a last run time if the last viewer was the same version
// because this stat will be counted against this version
- gLastExecDuration = markerIsSameVersion(start_marker_file_name) ? elapsed_seconds : -1;
+ if ( markerIsSameVersion(start_marker_file_name) )
+ {
+ gLastExecDuration = elapsed_seconds;
+ }
+ else
+ {
+ duration_log_stream << "start marker from some other version; duration is not reported";
+ gLastExecDuration = -1;
+ }
}
else
{
// at least one of the LLFile::stat calls failed, so we can't compute the run time
+ duration_log_stream << "duration stat failure; start: "<< start_stat_result << " log: " << log_stat_result;
gLastExecDuration = -1; // unknown
}
+ std::string duration_log_msg(duration_log_stream.str());
// Create a new start marker file for comparison with log file time for the next run
LLAPRFile start_marker_file ;
- start_marker_file.open(start_marker_file_name, LL_APR_W);
+ start_marker_file.open(start_marker_file_name, LL_APR_WB);
if (start_marker_file.getFileHandle())
{
recordMarkerVersion(start_marker_file);
@@ -2179,6 +2195,10 @@ void LLAppViewer::initLogging()
// Set the log file to SecondLife.log
LLError::logToFile(log_file);
+ if (!duration_log_msg.empty())
+ {
+ LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
+ }
}
bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
@@ -2756,7 +2776,6 @@ bool LLAppViewer::initConfiguration()
//
// Check for another instance of the app running
//
- mSecondInstance = anotherInstanceRunning();
if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
{
std::ostringstream msg;
@@ -2768,8 +2787,6 @@ bool LLAppViewer::initConfiguration()
return false;
}
- initMarkerFile();
-
if (mSecondInstance)
{
// This is the second instance of SL. Turn off voice support,
@@ -2970,26 +2987,26 @@ namespace {
{
LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL;
- // truncate version at the rightmost '.'
- std::string version_short(data["version"]);
- size_t short_length = version_short.rfind('.');
- if (short_length != std::string::npos)
- {
- version_short.resize(short_length);
- }
+ // truncate version at the rightmost '.'
+ std::string version_short(data["version"]);
+ size_t short_length = version_short.rfind('.');
+ if (short_length != std::string::npos)
+ {
+ version_short.resize(short_length);
+ }
- LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]");
- relnotes_url.setArg("[VERSION_SHORT]", version_short);
+ LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]");
+ relnotes_url.setArg("[VERSION_SHORT]", version_short);
- // *TODO thread the update service's response through to this point
- std::string const & channel = LLVersionInfo::getChannel();
- boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free);
+ // *TODO thread the update service's response through to this point
+ std::string const & channel = LLVersionInfo::getChannel();
+ boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free);
- relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get());
- relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));
+ relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get());
+ relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));
substitutions["INFO_URL"] = relnotes_url.getString();
}
-
+
LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);
}
@@ -3455,21 +3472,21 @@ void LLAppViewer::handleViewerCrash()
//we're already in a crash situation
if (gDirUtilp)
{
- std::string crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- gLLErrorActivated
- ? LLERROR_MARKER_FILE_NAME
- : ERROR_MARKER_FILE_NAME);
- LLAPRFile crash_file ;
- crash_file.open(crash_file_name, LL_APR_W);
- if (crash_file.getFileHandle())
+ std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ gLLErrorActivated
+ ? LLERROR_MARKER_FILE_NAME
+ : ERROR_MARKER_FILE_NAME);
+ LLAPRFile crash_marker_file ;
+ crash_marker_file.open(crash_marker_file_name, LL_APR_WB);
+ if (crash_marker_file.getFileHandle())
{
- LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
- recordMarkerVersion(crash_file);
+ LL_INFOS("MarkerFile") << "Created crash marker file " << crash_marker_file_name << LL_ENDL;
+ recordMarkerVersion(crash_marker_file);
}
else
{
- LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL;
- }
+ LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL;
+ }
}
else
{
@@ -3520,38 +3537,6 @@ void LLAppViewer::handleViewerCrash()
return;
}
-bool LLAppViewer::anotherInstanceRunning()
-{
- // We create a marker file when the program starts and remove the file when it finishes.
- // If the file is currently locked, that means another process is already running.
-
- std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME);
- LL_DEBUGS("MarkerFile") << "Checking marker file '"<< marker_file << "' for lock..." << LL_ENDL;
-
- //Freeze case checks
- if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
- {
- // File exists, try opening with write permissions
- LLAPRFile outfile ;
- outfile.open(marker_file, LL_APR_AB);
- apr_file_t* fMarker = outfile.getFileHandle() ;
- if (!fMarker)
- {
- // Another instance is running. Skip the rest of these operations.
- LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL;
- return true;
- }
- if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1)
- {
- LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL;
- return true;
- }
- // No other instances; we'll lock this file now & delete on quit.
- }
- LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL;
- return false;
-}
-
// static
void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)
{
@@ -3596,14 +3581,8 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
return sameVersion;
}
-void LLAppViewer::initMarkerFile()
+void LLAppViewer::processMarkerFiles()
{
- //First, check for the existence of other files.
- //There are marker files for two different types of crashes
-
- mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
- LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
-
//We've got 4 things to test for here
// - Other Process Running (SecondLife.exec_marker present, locked)
// - Freeze (SecondLife.exec_marker present, not locked)
@@ -3611,29 +3590,92 @@ void LLAppViewer::initMarkerFile()
// - Other Crash (SecondLife.error_marker present)
// These checks should also remove these files for the last 2 cases if they currently exist
- //LLError/Error checks. Only one of these should ever happen at a time.
- std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
- std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
- std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
-
- if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())
+ bool marker_is_same_version = true;
+ // first, look for the marker created at startup and deleted on a clean exit
+ mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
+ if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB))
{
- if ( markerIsSameVersion(mMarkerFileName) )
+ // File exists...
+ // first, read it to see if it was created by the same version (we need this later)
+ marker_is_same_version = markerIsSameVersion(mMarkerFileName);
+
+ // now test to see if this file is locked by a running process (try to open for write)
+ LL_DEBUGS("MarkerFile") << "Checking exec marker file for lock..." << LL_ENDL;
+ mMarkerFile.open(mMarkerFileName, LL_APR_WB);
+ apr_file_t* fMarker = mMarkerFile.getFileHandle() ;
+ if (!fMarker)
+ {
+ LL_INFOS("MarkerFile") << "Exec marker file open failed - assume it is locked." << LL_ENDL;
+ mSecondInstance = true; // lock means that instance is running.
+ }
+ else
{
- LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found" << LL_ENDL;
+ // We were able to open it, now try to lock it ourselves...
+ if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Locking exec marker failed." << LL_ENDL;
+ mSecondInstance = true; // lost a race? be conservative
+ }
+ else
+ {
+ // No other instances; we've locked this file now, so record our version; delete on quit.
+ recordMarkerVersion(mMarkerFile);
+ LL_DEBUGS("MarkerFile") << "Exec marker file existed but was not locked; rewritten." << LL_ENDL;
+ }
+ }
+
+ if (mSecondInstance)
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL;
+ }
+ else if (marker_is_same_version)
+ {
+ // the file existed, is ours, and matched our version, so we can report on what it says
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL;
gLastExecEvent = LAST_EXEC_FROZE;
+
}
else
{
LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;
}
- }
+ }
+ else // marker did not exist... last exec (if any) did not freeze
+ {
+ // Create the marker file for this execution & lock it; it will be deleted on a clean exit
+ apr_status_t s;
+ s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE);
+
+ if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL;
+ if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))
+ {
+ recordMarkerVersion(mMarkerFile);
+ LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL;
+ }
+ }
+
+ // now check for cases in which the exec marker may have been cleaned up by crash handlers
+
+ // check for any last exec event report based on whether or not it happened during logout
+ // (the logout marker is created when logout begins)
+ std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
{
if (markerIsSameVersion(logout_marker_file))
{
gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
- LL_INFOS("MarkerFile") << "Logout crashed '"<< logout_marker_file << "', setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL;
}
else
{
@@ -3641,89 +3683,86 @@ void LLAppViewer::initMarkerFile()
}
LLAPRFile::remove(logout_marker_file);
}
+ // further refine based on whether or not a marker created during an llerr crash is found
+ std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
{
if (markerIsSameVersion(llerror_marker_file))
{
- gLastExecEvent = ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
- ? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_LLERROR_CRASH;
- LL_INFOS("MarkerFile") << "Last exec LLError '"<< llerror_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
+ }
+ else
+ {
+ gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
+ }
}
else
{
- LL_INFOS("MarkerFile") << "Last exec LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
}
LLAPRFile::remove(llerror_marker_file);
}
+ // and last refine based on whether or not a marker created during a non-llerr crash is found
+ std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
{
if (markerIsSameVersion(error_marker_file))
{
- gLastExecEvent = (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
- ? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
+ }
+ else
+ {
+ gLastExecEvent = LAST_EXEC_OTHER_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
}
else
{
- LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
}
LLAPRFile::remove(error_marker_file);
}
-
- // No new markers if another instance is running.
- if(anotherInstanceRunning())
- {
- return;
- }
-
- // Create the marker file for this execution & lock it
- apr_status_t s;
- s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);
-
- if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
- {
- LL_DEBUGS("MarkerFile") << "Marker file '"<< mMarkerFileName << "' created." << LL_ENDL;
- if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))
- {
- recordMarkerVersion(mMarkerFile);
- LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL;
- }
- else
- {
- LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS("MarkerFile") << "Failed to create marker file '"<< mMarkerFileName << "'." << LL_ENDL;
- }
}
void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
{
- LL_DEBUGS("MarkerFile") << "removeMarkerFile("<<(leave_logout_marker?"leave":"remove") <<" logout)" << LL_ENDL;
- if (mMarkerFile.getFileHandle())
- {
- LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
- mMarkerFile.close();
- LLAPRFile::remove( mMarkerFileName );
- }
- else
- {
- LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
- }
- if (!leave_logout_marker)
- {
- if (mLogoutMarkerFile.getFileHandle())
+ if (!mSecondInstance)
+ {
+ LL_DEBUGS("MarkerFile") << (leave_logout_marker?"leave":"remove") <<" logout" << LL_ENDL;
+ if (mMarkerFile.getFileHandle())
{
- LL_DEBUGS("MarkerFile") << "removeMarkerFile logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
- mLogoutMarkerFile.close();
+ LL_DEBUGS("MarkerFile") << "removing exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
+ mMarkerFile.close() ;
+ LLAPRFile::remove( mMarkerFileName );
}
else
{
- LL_WARNS("MarkerFile") << "removeMarkerFile logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
+ LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
}
- LLAPRFile::remove( mLogoutMarkerFileName );
+ if (!leave_logout_marker)
+ {
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "removing logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
+ mLogoutMarkerFile.close();
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
+ }
+ LLAPRFile::remove( mLogoutMarkerFileName );
+ }
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "leaving markers because this is a second instance" << LL_ENDL;
}
}
@@ -3778,6 +3817,12 @@ void LLAppViewer::requestQuit()
gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
}
+ // Try to send last batch of avatar rez metrics.
+ if (!gDisconnected && isAgentAvatarValid())
+ {
+ gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
+ }
+
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
effectp->setPositionGlobal(gAgent.getPositionGlobal());
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
@@ -4916,6 +4961,22 @@ void LLAppViewer::sendLogoutRequest()
{
if(!mLogoutRequestSent && gMessageSystem)
{
+ //Set internal status variables and marker files before actually starting the logout process
+ gLogoutInProgress = TRUE;
+ mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
+
+ LLAPRFile outfile ;
+ mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
+ recordMarkerVersion(outfile);
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
+ }
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LogoutRequest);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -4931,22 +4992,6 @@ void LLAppViewer::sendLogoutRequest()
{
LLVoiceClient::getInstance()->leaveChannel();
}
-
- //Set internal status variables and marker files
- gLogoutInProgress = TRUE;
- mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
-
- LLAPRFile outfile ;
- mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_W);
- if (mLogoutMarkerFile.getFileHandle())
- {
- LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << mLogoutMarkerFileName << LL_ENDL;
- recordMarkerVersion(outfile);
- }
- else
- {
- LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
- }
}
}
@@ -5195,11 +5240,12 @@ void LLAppViewer::disconnectViewer()
void LLAppViewer::forceErrorLLError()
{
- llerrs << "This is an llerror" << llendl;
+ llerrs << "This is a deliberate llerror" << llendl;
}
void LLAppViewer::forceErrorBreakpoint()
{
+ llwarns << "Forcing a deliberate breakpoint" << llendl;
#ifdef LL_WINDOWS
DebugBreak();
#endif
@@ -5208,6 +5254,7 @@ void LLAppViewer::forceErrorBreakpoint()
void LLAppViewer::forceErrorBadMemoryAccess()
{
+ llwarns << "Forcing a deliberate bad memory access" << llendl;
S32* crash = NULL;
*crash = 0xDEADBEEF;
return;
@@ -5215,6 +5262,7 @@ void LLAppViewer::forceErrorBadMemoryAccess()
void LLAppViewer::forceErrorInfiniteLoop()
{
+ llwarns << "Forcing a deliberate infinite loop" << llendl;
while(true)
{
;
@@ -5224,12 +5272,14 @@ void LLAppViewer::forceErrorInfiniteLoop()
void LLAppViewer::forceErrorSoftwareException()
{
+ llwarns << "Forcing a deliberate exception" << llendl;
// *FIX: Any way to insure it won't be handled?
throw;
}
void LLAppViewer::forceErrorDriverCrash()
{
+ llwarns << "Forcing a deliberate driver crash" << llendl;
glDeleteTextures(1, NULL);
}
@@ -5342,7 +5392,7 @@ void LLAppViewer::handleLoginComplete()
void LLAppViewer::launchUpdater()
{
- LLSD query_map = LLSD::emptyMap();
+ LLSD query_map = LLSD::emptyMap();
query_map["os"] = gPlatform;
// *TODO change userserver to be grid on both viewer and sim, since
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index d3a8cf24d9..cd91ae8b2b 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -183,7 +183,7 @@ public:
protected:
virtual bool initWindow(); // Initialize the viewer's window.
- virtual void initLogging(); // Initialize log files, logging system
+ virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system
virtual void initConsole() {}; // Initialize OS level debugging console.
virtual bool initHardwareTest() { return true; } // A false result indicates the app should quit.
virtual bool initSLURLHandler();
@@ -215,8 +215,7 @@ private:
void writeSystemInfo(); // Write system info to "debug_info.log"
- bool anotherInstanceRunning();
- void initMarkerFile();
+ void processMarkerFiles();
static void recordMarkerVersion(LLAPRFile& marker_file);
bool markerIsSameVersion(const std::string& marker_name) const;
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 5f98fd0a34..b16bb573e1 100755
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -440,7 +440,7 @@ bool LLAppViewerLinux::beingDebugged()
#endif
}
-void LLAppViewerLinux::initLogging()
+void LLAppViewerLinux::initLoggingAndGetLastDuration()
{
// Remove the last stack trace, if any
// This file is no longer created, since the move to Google Breakpad
@@ -449,7 +449,7 @@ void LLAppViewerLinux::initLogging()
gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
LLFile::remove(old_stack_file);
- LLAppViewer::initLogging();
+ LLAppViewer::initLoggingAndGetLastDuration();
}
bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp)
diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h
index b30977acb3..fb77600c10 100755
--- a/indra/newview/llappviewerlinux.h
+++ b/indra/newview/llappviewerlinux.h
@@ -63,7 +63,7 @@ protected:
virtual bool restoreErrorTrap();
virtual void handleCrashReporting(bool reportFreeze);
- virtual void initLogging();
+ virtual void initLoggingAndGetLastDuration();
virtual bool initParseCommandLine(LLCommandLineParser& clp);
virtual bool initSLURLHandler();
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 0ba3669487..3cf3c739d9 100755
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -490,7 +490,7 @@ bool LLAppViewerWin32::init()
// (Don't send our data to Microsoft--at least until we are Logo approved and have a way
// of getting the data back from them.)
//
- llinfos << "Turning off Windows error reporting." << llendl;
+ // llinfos << "Turning off Windows error reporting." << llendl;
disableWinErrorReporting();
#ifndef LL_RELEASE_FOR_DOWNLOAD
@@ -509,9 +509,9 @@ bool LLAppViewerWin32::cleanup()
return result;
}
-void LLAppViewerWin32::initLogging()
+void LLAppViewerWin32::initLoggingAndGetLastDuration()
{
- LLAppViewer::initLogging();
+ LLAppViewer::initLoggingAndGetLastDuration();
}
void LLAppViewerWin32::initConsole()
diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h
index d95174dd1d..386bddd495 100755
--- a/indra/newview/llappviewerwin32.h
+++ b/indra/newview/llappviewerwin32.h
@@ -44,7 +44,7 @@ public:
virtual bool cleanup();
protected:
- virtual void initLogging(); // Override to clean stack_trace info.
+ virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info.
virtual void initConsole(); // Initialize OS level debugging console.
virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.
virtual bool initParseCommandLine(LLCommandLineParser& clp);
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 47306d3a6a..8c9fd4152a 100755
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -308,6 +308,49 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
}
+LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp)
+{
+ LLFace *face;
+ face = new LLFace(this, mVObjp);
+
+ face->setTEOffset(mFaces.size());
+ face->setTexture(texturep);
+ face->setNormalMap(normalp);
+ face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
+
+ mFaces.push_back(face);
+
+ if (isState(UNLIT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+
+ return face;
+
+}
+
+LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp)
+{
+ LLFace *face;
+ face = new LLFace(this, mVObjp);
+
+ face->setTEOffset(mFaces.size());
+ face->setTexture(texturep);
+ face->setNormalMap(normalp);
+ face->setSpecularMap(specularp);
+ face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
+
+ mFaces.push_back(face);
+
+ if (isState(UNLIT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+
+ return face;
+
+}
+
void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
if (newFaces == (S32)mFaces.size())
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 4420a34fae..c3f6d77edc 100755
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -145,6 +145,8 @@ public:
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep);
+ LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp);
+ LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp);
void deleteFaces(S32 offset, S32 count);
void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 94dd927d26..04e31e6486 100755
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -35,6 +35,7 @@
#include "lldrawpoolalpha.h"
#include "lldrawpoolavatar.h"
#include "lldrawpoolbump.h"
+#include "lldrawpoolmaterials.h"
#include "lldrawpoolground.h"
#include "lldrawpoolsimple.h"
#include "lldrawpoolsky.h"
@@ -47,6 +48,7 @@
#include "llspatialpartition.h"
#include "llviewercamera.h"
#include "lldrawpoolwlsky.h"
+#include "llglslshader.h"
S32 LLDrawPool::sNumDrawPools = 0;
@@ -64,6 +66,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_GRASS:
poolp = new LLDrawPoolGrass();
break;
+ case POOL_ALPHA_MASK:
+ poolp = new LLDrawPoolAlphaMask();
+ break;
+ case POOL_FULLBRIGHT_ALPHA_MASK:
+ poolp = new LLDrawPoolFullbrightAlphaMask();
+ break;
case POOL_FULLBRIGHT:
poolp = new LLDrawPoolFullbright();
break;
@@ -98,6 +106,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_BUMP:
poolp = new LLDrawPoolBump();
break;
+ case POOL_MATERIALS:
+ poolp = new LLDrawPoolMaterials();
+ break;
case POOL_WL_SKY:
poolp = new LLDrawPoolWLSky();
break;
@@ -411,6 +422,27 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text
}
}
+void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
+{
+ for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ {
+ LLDrawInfo* pparams = *i;
+ if (pparams)
+ {
+ if (LLGLSLShader::sCurBoundShaderPtr)
+ {
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff);
+ }
+
+ pushBatch(*pparams, mask, texture, batch_textures);
+ }
+ }
+}
+
void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
{
if (params.mModelMatrix != gGLLastMatrix)
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index ab9bb9e611..3bde0d29be 100755
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -50,10 +50,13 @@ public:
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, // see below *
POOL_AVATAR,
@@ -133,6 +136,22 @@ public:
PASS_SHINY,
PASS_BUMP,
PASS_POST_BUMP,
+ PASS_MATERIAL,
+ PASS_MATERIAL_ALPHA,
+ PASS_MATERIAL_ALPHA_MASK,
+ PASS_MATERIAL_ALPHA_EMISSIVE,
+ PASS_SPECMAP,
+ PASS_SPECMAP_BLEND,
+ PASS_SPECMAP_MASK,
+ PASS_SPECMAP_EMISSIVE,
+ PASS_NORMMAP,
+ PASS_NORMMAP_BLEND,
+ PASS_NORMMAP_MASK,
+ PASS_NORMMAP_EMISSIVE,
+ PASS_NORMSPEC,
+ PASS_NORMSPEC_BLEND,
+ PASS_NORMSPEC_MASK,
+ PASS_NORMSPEC_EMISSIVE,
PASS_GLOW,
PASS_ALPHA,
PASS_ALPHA_MASK,
@@ -151,6 +170,7 @@ public:
static void applyModelMatrix(LLDrawInfo& params);
virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
+ virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 313b310e1e..c832e1401d 100755
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -71,33 +71,6 @@ void LLDrawPoolAlpha::prerender()
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
-S32 LLDrawPoolAlpha::getNumDeferredPasses()
-{
- return 1;
-}
-
-void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
-{
-
-}
-
-void LLDrawPoolAlpha::endDeferredPass(S32 pass)
-{
-
-}
-
-void LLDrawPoolAlpha::renderDeferred(S32 pass)
-{
- LLFastTimer t(FTM_RENDER_GRASS);
- gDeferredDiffuseAlphaMaskProgram.bind();
- gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
-
- //render alpha masked objects
- LLRenderPass::pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- gDeferredDiffuseAlphaMaskProgram.unbind();
-}
-
-
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
{
if (LLPipeline::sImpostorRender)
@@ -121,8 +94,10 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
if (pass == 0)
{
simple_shader = &gDeferredAlphaProgram;
- fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
-
+ fullbright_shader = &gObjectFullbrightProgram;
+ fullbright_shader->bind();
+ fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ fullbright_shader->unbind();
//prime simple shader (loads shadow relevant uniforms)
gPipeline.bindDeferredShader(*simple_shader);
}
@@ -133,8 +108,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
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();
- simple_shader = NULL;
- fullbright_shader = NULL;
+ simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
gObjectFullbrightAlphaMaskProgram.bind();
gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
}
@@ -150,7 +124,6 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
-
if (pass == 1)
{
gPipeline.mDeferredDepth.flush();
@@ -173,14 +146,14 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
if (LLPipeline::sUnderWaterRender)
{
- simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
- fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram;
+ simple_shader = &gObjectSimpleWaterProgram;
+ fullbright_shader = &gObjectFullbrightWaterProgram;
emissive_shader = &gObjectEmissiveWaterProgram;
}
else
{
- simple_shader = &gObjectSimpleAlphaMaskProgram;
- fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
+ simple_shader = &gObjectSimpleProgram;
+ fullbright_shader = &gObjectFullbrightProgram;
emissive_shader = &gObjectEmissiveProgram;
}
@@ -218,43 +191,7 @@ void LLDrawPoolAlpha::render(S32 pass)
{
gGL.setColorMask(true, true);
}
-
- if (LLPipeline::sAutoMaskAlphaNonDeferred)
- {
- mColorSFactor = LLRender::BF_ONE; // }
- mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow
- mAlphaSFactor = LLRender::BF_ZERO;
- mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- if (mVertexShaderLevel > 0)
- {
- if (!LLPipeline::sRenderDeferred || !deferred_render)
- {
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.33f);
-
- pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- }
- if (fullbright_shader)
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.33f);
- }
- pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- //LLGLSLShader::bindNoShader();
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); //OK
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
- pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
- gPipeline.enableLightsDynamic();
- pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
- }
- }
-
+
LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||
(deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
@@ -302,7 +239,7 @@ void LLDrawPoolAlpha::render(S32 pass)
if (mVertexShaderLevel > 0)
{
- renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX);
+ renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
}
else
{
@@ -412,8 +349,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
LLRenderPass::applyModelMatrix(params);
-
+ LLMaterial* mat = NULL;
+
+ if (deferred_render && !LLPipeline::sUnderWaterRender)
+ {
+ mat = params.mMaterial;
+ }
+
if (params.mFullbright)
{
// Turn off lighting if it hasn't already been so.
@@ -446,11 +389,30 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
light_enabled = TRUE;
}
- // If we need shaders, and we're not ALREADY using the proper shader, then bind it
- // (this way we won't rebind shaders unnecessarily).
- if(use_shaders && (current_shader != target_shader))
+ if (deferred_render && mat)
{
- llassert(target_shader != NULL);
+ U32 mask = params.mShaderMask;
+
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = &(gDeferredMaterialProgram[mask]);
+
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShader(*target_shader);
+ }
+ }
+ else if (!params.mFullbright)
+ {
+ target_shader = simple_shader;
+ }
+ else
+ {
+ target_shader = fullbright_shader;
+ }
+
+ if(use_shaders && (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).
current_shader = target_shader;
current_shader->bind();
}
@@ -459,6 +421,38 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
LLGLSLShader::bindNoShader();
current_shader = NULL;
}
+
+ if (use_shaders && mat)
+ {
+ // We have a material. Supply the appropriate data here.
+ if (LLPipeline::sRenderDeferred)
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
+
+ if (params.mNormalMap)
+ {
+ params.mNormalMap->addTextureStats(params.mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap);
+ }
+
+ if (params.mSpecularMap)
+ {
+ params.mSpecularMap->addTextureStats(params.mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap);
+ }
+ }
+
+ } else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader))
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
+ LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
if (params.mGroup)
{
@@ -477,12 +471,20 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
}
}
- else
+ else
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
if (params.mTexture.notNull())
{
params.mTexture->addTextureStats(params.mVSize);
- gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
+ if (use_shaders && mat)
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(params.mTexture, TRUE);
+ }
+
if (params.mTextureMatrix)
{
tex_setup = true;
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index a4245e561d..43122218ed 100755
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -50,11 +50,6 @@ public:
LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);
/*virtual*/ ~LLDrawPoolAlpha();
- /*virtual*/ S32 getNumDeferredPasses();
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
- /*virtual*/ void renderDeferred(S32 pass);
-
/*virtual*/ S32 getNumPostDeferredPasses();
/*virtual*/ void beginPostDeferredPass(S32 pass);
/*virtual*/ void endPostDeferredPass(S32 pass);
@@ -70,7 +65,7 @@ public:
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
void renderAlpha(U32 mask);
void renderAlphaHighlight(U32 mask);
-
+
static BOOL sShowDebugAlpha;
private:
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 294cecc703..075299386e 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -62,6 +62,7 @@ S32 LLDrawPoolAvatar::sDiffuseChannel = 0;
static bool is_deferred_render = false;
+static bool is_post_deferred_render = false;
extern BOOL gUseGLPick;
@@ -183,6 +184,9 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
case 4:
beginDeferredRiggedBump();
break;
+ default:
+ beginDeferredRiggedMaterial(pass-5);
+ break;
}
}
@@ -215,6 +219,9 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)
case 4:
endDeferredRiggedBump();
break;
+ default:
+ endDeferredRiggedMaterial(pass-5);
+ break;
}
}
@@ -225,7 +232,7 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass)
S32 LLDrawPoolAvatar::getNumPostDeferredPasses()
{
- return 6;
+ return 10;
}
void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
@@ -247,9 +254,12 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
case 4:
beginRiggedFullbrightAlpha();
break;
- case 5:
+ case 9:
beginRiggedGlow();
break;
+ default:
+ beginDeferredRiggedMaterialAlpha(pass-5);
+ break;
}
}
@@ -275,11 +285,34 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
gPipeline.enableLightsDynamic();
}
+void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
+{
+ switch (pass)
+ {
+ case 0: pass = 1; break;
+ case 1: pass = 5; break;
+ case 2: pass = 9; break;
+ default: pass = 13; break;
+ }
+
+ pass += LLMaterial::SHADER_COUNT;
+
+ sVertexProgram = &gDeferredMaterialProgram[pass];
+
+ gPipeline.bindDeferredShader(*sVertexProgram);
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
+ gPipeline.enableLightsDynamic();
+}
+
void LLDrawPoolAvatar::endDeferredRiggedAlpha()
{
LLVertexBuffer::unbind();
gPipeline.unbindDeferredShader(*sVertexProgram);
sDiffuseChannel = 0;
+ normal_channel = -1;
+ specular_channel = -1;
sVertexProgram = NULL;
}
@@ -305,6 +338,9 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)
case 5:
endRiggedGlow();
break;
+ default:
+ endDeferredRiggedAlpha();
+ break;
}
}
@@ -328,17 +364,23 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
6, //rigged fullbright shiny
7, //rigged alpha
8, //rigged fullbright alpha
- 9, //rigged glow
+ 9, //rigged material alpha 1
+ 10,//rigged material alpha 2
+ 11,//rigged material alpha 3
+ 12,//rigged material alpha 4
+ 13, //rigged glow
};
- pass = actual_pass[pass];
+ S32 p = actual_pass[pass];
if (LLPipeline::sImpostorRender)
{ //HACK for impostors so actual pass ends up being proper pass
- pass -= 2;
+ p -= 2;
}
- render(pass);
+ is_post_deferred_render = true;
+ render(p);
+ is_post_deferred_render = false;
}
@@ -425,12 +467,10 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
}
else
{
- renderRigged(avatarp, RIGGED_SIMPLE);
- renderRigged(avatarp, RIGGED_ALPHA);
- renderRigged(avatarp, RIGGED_FULLBRIGHT);
- renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY);
- renderRigged(avatarp, RIGGED_SHINY);
- renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA);
+ for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
+ {
+ renderRigged(avatarp, i);
+ }
}
}
@@ -455,7 +495,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
}
else
{
- return 5;
+ return 21;
}
}
@@ -839,6 +879,8 @@ void LLDrawPoolAvatar::beginRiggedGlow()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
+
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
}
}
@@ -857,7 +899,14 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
}
else
{
- sVertexProgram = &gSkinnedObjectFullbrightProgram;
+ if (LLPipeline::sRenderDeferred)
+ {
+ sVertexProgram = &gDeferredSkinnedFullbrightProgram;
+ }
+ else
+ {
+ sVertexProgram = &gSkinnedObjectFullbrightProgram;
+ }
}
}
else
@@ -876,6 +925,15 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
+
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ else
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
}
}
@@ -942,7 +1000,14 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
}
else
{
- sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
+ if (LLPipeline::sRenderDeferred)
+ {
+ sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram;
+ }
+ else
+ {
+ sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
+ }
}
}
else
@@ -957,11 +1022,19 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
}
}
-
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
sVertexProgram->bind();
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
+
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ else
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
}
}
@@ -1010,6 +1083,42 @@ void LLDrawPoolAvatar::endDeferredRiggedBump()
sVertexProgram = NULL;
}
+void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
+{
+ if (pass == 1 ||
+ pass == 5 ||
+ pass == 9 ||
+ pass == 13)
+ { //skip alpha passes
+ return;
+ }
+ sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT];
+ sVertexProgram->bind();
+ normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+}
+
+void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
+{
+ if (pass == 1 ||
+ pass == 5 ||
+ pass == 9 ||
+ pass == 13)
+ {
+ return;
+ }
+
+ LLVertexBuffer::unbind();
+ sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
+ sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
+ sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ sVertexProgram->unbind();
+ normal_channel = -1;
+ sDiffuseChannel = 0;
+ sVertexProgram = NULL;
+}
+
void LLDrawPoolAvatar::beginDeferredSkinned()
{
sShaderLevel = mVertexShaderLevel;
@@ -1167,6 +1276,22 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
else
{
renderRiggedSimple(avatarp);
+
+ if (LLPipeline::sRenderDeferred)
+ { //render "simple" materials
+ renderRigged(avatarp, RIGGED_MATERIAL);
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK);
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMMAP);
+ renderRigged(avatarp, RIGGED_NORMMAP_MASK);
+ renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_SPECMAP);
+ renderRigged(avatarp, RIGGED_SPECMAP_MASK);
+ renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMSPEC);
+ renderRigged(avatarp, RIGGED_NORMSPEC_MASK);
+ renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
+ }
}
return;
}
@@ -1185,9 +1310,27 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
+ if (is_deferred_render && pass >= 5 && pass <= 21)
+ {
+ S32 p = pass-5;
+
+ if (p != 1 &&
+ p != 5 &&
+ p != 9 &&
+ p != 13)
+ {
+ renderDeferredRiggedMaterial(avatarp, p);
+ }
+ return;
+ }
+
+
+
+
if (pass == 5)
{
renderRiggedShinySimple(avatarp);
+
return;
}
@@ -1197,11 +1340,29 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
- if (pass >= 7 && pass < 9)
+ if (pass >= 7 && pass < 13)
{
if (pass == 7)
{
renderRiggedAlpha(avatarp);
+
+ if (LLPipeline::sRenderDeferred && !is_post_deferred_render)
+ { //render transparent materials under water
+ LLGLEnable blend(GL_BLEND);
+
+ gGL.setColorMask(true, true);
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
+ LLRender::BF_ZERO,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
+ renderRigged(avatarp, RIGGED_SPECMAP_BLEND);
+ renderRigged(avatarp, RIGGED_NORMMAP_BLEND);
+ renderRigged(avatarp, RIGGED_NORMSPEC_BLEND);
+
+ gGL.setColorMask(true, false);
+ }
return;
}
@@ -1210,9 +1371,32 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
renderRiggedFullbrightAlpha(avatarp);
return;
}
+
+ if (LLPipeline::sRenderDeferred && is_post_deferred_render)
+ {
+ S32 p = 0;
+ switch (pass)
+ {
+ case 9: p = 1; break;
+ case 10: p = 5; break;
+ case 11: p = 9; break;
+ case 12: p = 13; break;
+ }
+
+ {
+ LLGLEnable blend(GL_BLEND);
+ renderDeferredRiggedMaterial(avatarp, p);
+ }
+ return;
+ }
+ else if (pass == 9)
+ {
+ renderRiggedGlow(avatarp);
+ return;
+ }
}
- if (pass == 9)
+ if (pass == 13)
{
renderRiggedGlow(avatarp);
@@ -1474,9 +1658,11 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
if (sShaderLevel > 0)
{ //upload matrix palette to shader
- LLMatrix4 mat[64];
+ LLMatrix4 mat[32];
+
+ U32 count = llmin((U32) skin->mJointNames.size(), (U32) 32);
- for (U32 i = 0; i < skin->mJointNames.size(); ++i)
+ for (U32 i = 0; i < count; ++i)
{
LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
if (joint)
@@ -1489,7 +1675,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
stop_glerror();
LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",
- skin->mJointNames.size(),
+ count,
FALSE,
(GLfloat*) mat[0].mMatrix);
@@ -1510,10 +1696,59 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
}*/
- gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
- if (normal_channel > -1)
+ const LLTextureEntry* te = face->getTextureEntry();
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ if (mat)
{
- LLDrawPoolBump::bindBumpMap(face, normal_channel);
+ gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP));
+ gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
+ gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP));
+
+ LLColor4 col = mat->getSpecularLightColor();
+ F32 spec = mat->getSpecularLightExponent()/255.f;
+
+ F32 env = mat->getEnvironmentIntensity()/255.f;
+
+ if (mat->getSpecularID().isNull())
+ {
+ env = te->getShiny()*0.25f;
+ col.set(env,env,env,0);
+ spec = env;
+ }
+
+ BOOL fullbright = te->getFullbright();
+
+ sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
+ sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
+ sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
+
+ if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
+ }
+ else
+ {
+ sVertexProgram->setMinimumAlpha(0.f);
+ }
+
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ LLViewerTexture* tex = face->getTexture(i);
+ if (tex)
+ {
+ tex->addTextureStats(avatar->getPixelArea());
+ }
+ }
+ }
+ else
+ {
+ gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
+ sVertexProgram->setMinimumAlpha(0.f);
+ if (normal_channel > -1)
+ {
+ LLDrawPoolBump::bindBumpMap(face, normal_channel);
+ }
}
if (face->mTextureMatrix)
@@ -1545,6 +1780,11 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
renderRigged(avatar, RIGGED_DEFERRED_BUMP);
}
+void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass)
+{
+ renderRigged(avatar, pass);
+}
+
static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO");
void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 69e3068858..7d0368a945 100755
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -75,7 +75,7 @@ public:
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
-
+
/*virtual*/ S32 getNumPostDeferredPasses();
/*virtual*/ void beginPostDeferredPass(S32 pass);
/*virtual*/ void endPostDeferredPass(S32 pass);
@@ -113,6 +113,8 @@ public:
void beginRiggedFullbrightAlpha();
void beginRiggedGlow();
void beginDeferredRiggedAlpha();
+ void beginDeferredRiggedMaterial(S32 pass);
+ void beginDeferredRiggedMaterialAlpha(S32 pass);
void endRiggedSimple();
void endRiggedFullbright();
@@ -122,6 +124,8 @@ public:
void endRiggedFullbrightAlpha();
void endRiggedGlow();
void endDeferredRiggedAlpha();
+ void endDeferredRiggedMaterial(S32 pass);
+ void endDeferredRiggedMaterialAlpha(S32 pass);
void beginDeferredRiggedSimple();
void beginDeferredRiggedBump();
@@ -146,10 +150,27 @@ public:
void renderRiggedGlow(LLVOAvatar* avatar);
void renderDeferredRiggedSimple(LLVOAvatar* avatar);
void renderDeferredRiggedBump(LLVOAvatar* avatar);
-
+ void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass);
+
typedef enum
{
- RIGGED_SIMPLE = 0,
+ RIGGED_MATERIAL=0,
+ RIGGED_MATERIAL_ALPHA,
+ RIGGED_MATERIAL_ALPHA_MASK,
+ RIGGED_MATERIAL_ALPHA_EMISSIVE,
+ RIGGED_SPECMAP,
+ RIGGED_SPECMAP_BLEND,
+ RIGGED_SPECMAP_MASK,
+ RIGGED_SPECMAP_EMISSIVE,
+ RIGGED_NORMMAP,
+ RIGGED_NORMMAP_BLEND,
+ RIGGED_NORMMAP_MASK,
+ RIGGED_NORMMAP_EMISSIVE,
+ RIGGED_NORMSPEC,
+ RIGGED_NORMSPEC_BLEND,
+ RIGGED_NORMSPEC_MASK,
+ RIGGED_NORMSPEC_EMISSIVE,
+ RIGGED_SIMPLE,
RIGGED_FULLBRIGHT,
RIGGED_SHINY,
RIGGED_FULLBRIGHT_SHINY,
@@ -164,6 +185,48 @@ public:
typedef enum
{
+ RIGGED_MATERIAL_MASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4,
+ RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK,
+ RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK,
+ RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK,
+ RIGGED_SPECMAP_VMASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD2 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4,
+ RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK,
+ RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK,
+ RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK,
+ RIGGED_NORMMAP_VMASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TANGENT |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD1 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4,
+ RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK,
+ RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK,
+ RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK,
+ RIGGED_NORMSPEC_VMASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TANGENT |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD1 |
+ LLVertexBuffer::MAP_TEXCOORD2 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4,
+ RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK,
+ RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK,
+ RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK,
RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
@@ -184,7 +247,7 @@ public:
RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_BINORMAL |
+ LLVertexBuffer::MAP_TANGENT |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_WEIGHT4,
RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index e8d43c8631..155e289c9d 100755
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -153,7 +153,7 @@ void LLStandardBumpmap::addstandard()
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =
LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ;
LLStandardBumpmap::sStandardBumpmapCount++;
@@ -449,9 +449,6 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
- cube_map->disable();
- cube_map->restoreMatrix();
-
if (!invisible && shader_level > 1)
{
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
@@ -464,6 +461,8 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
}
}
}
+ cube_map->disable();
+ cube_map->restoreMatrix();
}
if (!LLGLSLShader::sNoFixedFunction)
@@ -514,7 +513,14 @@ void LLDrawPoolBump::beginFullbrightShiny()
}
else
{
- shader = &gObjectFullbrightShinyProgram;
+ if (LLPipeline::sRenderDeferred)
+ {
+ shader = &gDeferredFullbrightShinyProgram;
+ }
+ else
+ {
+ shader = &gObjectFullbrightShinyProgram;
+ }
}
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
@@ -850,7 +856,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
@@ -915,6 +921,8 @@ void LLBumpImageList::init()
llassert( mDarknessEntries.size() == 0 );
LLStandardBumpmap::init();
+
+ LLStandardBumpmap::restoreGL();
}
void LLBumpImageList::clear()
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
new file mode 100644
index 0000000000..08a36bddf1
--- /dev/null
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -0,0 +1,217 @@
+/**
+ * @file lldrawpool.cpp
+ * @brief LLDrawPoolMaterials class implementation
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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 "lldrawpoolmaterials.h"
+#include "llviewershadermgr.h"
+#include "pipeline.h"
+
+S32 diffuse_channel = -1;
+
+LLDrawPoolMaterials::LLDrawPoolMaterials()
+: LLRenderPass(LLDrawPool::POOL_MATERIALS)
+{
+
+}
+
+void LLDrawPoolMaterials::prerender()
+{
+ mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+S32 LLDrawPoolMaterials::getNumDeferredPasses()
+{
+ return 12;
+}
+
+void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
+{
+ U32 shader_idx[] =
+ {
+ 0, //LLRenderPass::PASS_MATERIAL,
+ //1, //LLRenderPass::PASS_MATERIAL_ALPHA,
+ 2, //LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ 3, //LLRenderPass::PASS_MATERIAL_ALPHA_GLOW,
+ 4, //LLRenderPass::PASS_SPECMAP,
+ //5, //LLRenderPass::PASS_SPECMAP_BLEND,
+ 6, //LLRenderPass::PASS_SPECMAP_MASK,
+ 7, //LLRenderPass::PASS_SPECMAP_GLOW,
+ 8, //LLRenderPass::PASS_NORMMAP,
+ //9, //LLRenderPass::PASS_NORMMAP_BLEND,
+ 10, //LLRenderPass::PASS_NORMMAP_MASK,
+ 11, //LLRenderPass::PASS_NORMMAP_GLOW,
+ 12, //LLRenderPass::PASS_NORMSPEC,
+ //13, //LLRenderPass::PASS_NORMSPEC_BLEND,
+ 14, //LLRenderPass::PASS_NORMSPEC_MASK,
+ 15, //LLRenderPass::PASS_NORMSPEC_GLOW,
+ };
+
+ mShader = &(gDeferredMaterialProgram[shader_idx[pass]]);
+ mShader->bind();
+
+ diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+}
+
+void LLDrawPoolMaterials::endDeferredPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+
+ mShader->unbind();
+
+ LLRenderPass::endRenderPass(pass);
+}
+
+void LLDrawPoolMaterials::renderDeferred(S32 pass)
+{
+ U32 type_list[] =
+ {
+ LLRenderPass::PASS_MATERIAL,
+ //LLRenderPass::PASS_MATERIAL_ALPHA,
+ LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ //LLRenderPass::PASS_SPECMAP_BLEND,
+ LLRenderPass::PASS_SPECMAP_MASK,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ //LLRenderPass::PASS_NORMMAP_BLEND,
+ LLRenderPass::PASS_NORMMAP_MASK,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ //LLRenderPass::PASS_NORMSPEC_BLEND,
+ LLRenderPass::PASS_NORMSPEC_MASK,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ };
+
+ llassert(pass < sizeof(type_list)/sizeof(U32));
+
+ U32 type = type_list[pass];
+
+ U32 mask = mShader->mAttributeMask;
+
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
+
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ {
+ LLDrawInfo& params = **i;
+
+ mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
+ mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
+
+ if (params.mNormalMap)
+ {
+ params.mNormalMap->addTextureStats(params.mVSize);
+ bindNormalMap(params.mNormalMap);
+ }
+
+ if (params.mSpecularMap)
+ {
+ params.mSpecularMap->addTextureStats(params.mVSize);
+ bindSpecularMap(params.mSpecularMap);
+ }
+
+ mShader->setMinimumAlpha(params.mAlphaMaskCutoff);
+ mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
+
+ pushBatch(params, mask, TRUE);
+ }
+}
+
+void LLDrawPoolMaterials::bindSpecularMap(LLViewerTexture* tex)
+{
+ mShader->bindTexture(LLShaderMgr::SPECULAR_MAP, tex);
+}
+
+void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)
+{
+ mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);
+}
+
+void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
+{
+ applyModelMatrix(params);
+
+ bool tex_setup = false;
+
+ if (batch_textures && params.mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < params.mTextureList.size(); ++i)
+ {
+ if (params.mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (params.mTextureMatrix)
+ {
+ //if (mShiny)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ }
+
+ gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+
+ tex_setup = true;
+ }
+
+ if (mVertexShaderLevel > 1 && texture)
+ {
+ if (params.mTexture.notNull())
+ {
+ gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
+ params.mTexture->addTextureStats(params.mVSize);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
+
+ if (params.mGroup)
+ {
+ params.mGroup->rebuildMesh();
+ }
+ params.mVertexBuffer->setBuffer(mask);
+ params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ if (tex_setup)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+}
diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h
new file mode 100644
index 0000000000..eae1aba87c
--- /dev/null
+++ b/indra/newview/lldrawpoolmaterials.h
@@ -0,0 +1,75 @@
+/**
+ * @file lldrawpoolmaterials.h
+ * @brief LLDrawPoolMaterials class definition
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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_LLDRAWPOOLMATERIALS_H
+#define LL_LLDRAWPOOLMATERIALS_H
+
+#include "v4coloru.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "llvertexbuffer.h"
+#include "lldrawpool.h"
+
+class LLViewerTexture;
+class LLDrawInfo;
+class LLGLSLShader;
+
+class LLDrawPoolMaterials : public LLRenderPass
+{
+ LLGLSLShader *mShader;
+public:
+ LLDrawPoolMaterials();
+
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD1 |
+ LLVertexBuffer::MAP_TEXCOORD2 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_TANGENT
+ };
+
+ /*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ /*virtual*/ void render(S32 pass = 0) { }
+ /*virtual*/ S32 getNumPasses() {return 0;}
+ /*virtual*/ void prerender();
+
+ /*virtual*/ S32 getNumDeferredPasses();
+ /*virtual*/ void beginDeferredPass(S32 pass);
+ /*virtual*/ void endDeferredPass(S32 pass);
+ /*virtual*/ void renderDeferred(S32 pass);
+
+ void bindSpecularMap(LLViewerTexture* tex);
+ void bindNormalMap(LLViewerTexture* tex);
+
+ /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
+};
+
+#endif //LL_LLDRAWPOOLMATERIALS_H
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index 6e0ea78af2..2cf9d833c6 100755
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -47,6 +47,7 @@ static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");
void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
{
gDeferredEmissiveProgram.bind();
+ gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
}
static LLFastTimer::DeclareTimer FTM_RENDER_GLOW_PUSH("Glow Push");
@@ -110,6 +111,7 @@ void LLDrawPoolGlow::render(S32 pass)
LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
shader->bind();
+ shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
gGL.setColorMask(false, true);
@@ -198,7 +200,11 @@ void LLDrawPoolSimple::render(S32 pass)
if (LLPipeline::sRenderDeferred)
{ //if deferred rendering is enabled, bump faces aren't registered as simple
//render bump faces here as simple so bump faces will appear under water
- pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);
}
}
else
@@ -210,6 +216,169 @@ void LLDrawPoolSimple::render(S32 pass)
}
}
+
+
+
+
+
+
+
+
+
+static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK("Alpha Mask");
+
+LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
+ LLRenderPass(POOL_ALPHA_MASK)
+{
+}
+
+void LLDrawPoolAlphaMask::prerender()
+{
+ mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
+ }
+ else
+ {
+ simple_shader = &gObjectSimpleAlphaMaskProgram;
+ }
+
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->bind();
+ }
+ else
+ {
+ // don't use shaders!
+ if (gGLManager.mHasShaderObjects)
+ {
+ LLGLSLShader::bindNoShader();
+ }
+ }
+}
+
+void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+ stop_glerror();
+ LLRenderPass::endRenderPass(pass);
+ stop_glerror();
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->unbind();
+ }
+}
+
+void LLDrawPoolAlphaMask::render(S32 pass)
+{
+ LLGLDisable blend(GL_BLEND);
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.33f);
+
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
+ else
+ {
+ LLGLEnable test(GL_ALPHA_TEST);
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+ }
+}
+
+LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
+ LLRenderPass(POOL_FULLBRIGHT_ALPHA_MASK)
+{
+}
+
+void LLDrawPoolFullbrightAlphaMask::prerender()
+{
+ mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ simple_shader = &gObjectFullbrightWaterAlphaMaskProgram;
+ }
+ else
+ {
+ simple_shader = &gObjectFullbrightAlphaMaskProgram;
+ }
+
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->bind();
+ }
+ else
+ {
+ // don't use shaders!
+ if (gGLManager.mHasShaderObjects)
+ {
+ LLGLSLShader::bindNoShader();
+ }
+ }
+}
+
+void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+ stop_glerror();
+ LLRenderPass::endRenderPass(pass);
+ stop_glerror();
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->unbind();
+ }
+}
+
+void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+
+ if (mVertexShaderLevel > 0)
+ {
+ if (simple_shader)
+ {
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.33f);
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ } else {
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ }
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ //LLGLSLShader::bindNoShader();
+ }
+ else
+ {
+ LLGLEnable test(GL_ALPHA_TEST);
+ gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
+ gPipeline.enableLightsDynamic();
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+ }
+}
+
//===============================
//DEFERRED IMPLEMENTATION
//===============================
@@ -239,6 +408,28 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)
}
}
+static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask");
+
+void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass)
+{
+
+}
+
+void LLDrawPoolAlphaMask::endDeferredPass(S32 pass)
+{
+
+}
+
+void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK_DEFERRED);
+ gDeferredDiffuseAlphaMaskProgram.bind();
+ gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ gDeferredDiffuseAlphaMaskProgram.unbind();
+}
+
+
// grass drawpool
LLDrawPoolGrass::LLDrawPoolGrass() :
LLRenderPass(POOL_GRASS)
@@ -403,14 +594,24 @@ void LLDrawPoolFullbright::render(S32 pass)
{
fullbright_shader->bind();
fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
+ fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f);
+
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE);
}
else
{
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);
+ pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask);
+ pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask);
+ pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask);
+ pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask);
}
stop_glerror();
@@ -421,3 +622,32 @@ S32 LLDrawPoolFullbright::getNumPasses()
return 1;
}
+
+void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
+{
+ gObjectFullbrightAlphaMaskProgram.bind();
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ else
+ {
+ gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+}
+
+void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_FULLBRIGHT);
+ LLGLDisable blend(GL_BLEND);
+ U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
+}
+
+void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
+{
+ gObjectFullbrightAlphaMaskProgram.unbind();
+ LLRenderPass::endRenderPass(pass);
+}
+
+
diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h
index bd62bc7502..608ad9e1eb 100755
--- a/indra/newview/lldrawpoolsimple.h
+++ b/indra/newview/lldrawpoolsimple.h
@@ -84,6 +84,59 @@ public:
/*virtual*/ void prerender();
};
+class LLDrawPoolAlphaMask : public LLRenderPass
+{
+public:
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR
+ };
+ virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ LLDrawPoolAlphaMask();
+
+ /*virtual*/ S32 getNumDeferredPasses() { return 1; }
+ /*virtual*/ void beginDeferredPass(S32 pass);
+ /*virtual*/ void endDeferredPass(S32 pass);
+ /*virtual*/ void renderDeferred(S32 pass);
+
+ /*virtual*/ S32 getNumPasses() { return 1; }
+ /*virtual*/ void beginRenderPass(S32 pass);
+ /*virtual*/ void endRenderPass(S32 pass);
+ /*virtual*/ void render(S32 pass = 0);
+ /*virtual*/ void prerender();
+
+};
+
+class LLDrawPoolFullbrightAlphaMask : public LLRenderPass
+{
+public:
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR
+ };
+ virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ LLDrawPoolFullbrightAlphaMask();
+
+ /*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
+ /*virtual*/ void beginPostDeferredPass(S32 pass);
+ /*virtual*/ void endPostDeferredPass(S32 pass);
+ /*virtual*/ void renderPostDeferred(S32 pass);
+
+ /*virtual*/ S32 getNumPasses() { return 1; }
+ /*virtual*/ void beginRenderPass(S32 pass);
+ /*virtual*/ void endRenderPass(S32 pass);
+ /*virtual*/ void render(S32 pass = 0);
+ /*virtual*/ void prerender();
+};
+
+
class LLDrawPoolFullbright : public LLRenderPass
{
public:
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 281f852b0a..f021f4ed0f 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -51,7 +51,7 @@
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llviewershadermgr.h"
-
+#include "llviewertexture.h"
#define LL_MAX_INDICES_COUNT 1000000
@@ -106,41 +106,6 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal,
tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f);
}
-void sphericalProjection(LLVector2 &tc, const LLVector4a& normal,
- const LLVector4a &mCenter, const LLVector4a& vec)
-{ //BROKEN
- /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f;
-
- tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f;
- if (vd.mNormal.mV[1] > 0)
- {
- tc.mV[1] = 1.0f-tc.mV[1];
- }*/
-}
-
-void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec)
-{ //BROKEN
- /*LLVector3 binormal;
- float d = vd.mNormal * LLVector3(1,0,0);
- if (d >= 0.5f || d <= -0.5f)
- {
- binormal = LLVector3(0,1,0);
- }
- else{
- binormal = LLVector3(1,0,0);
- }
- LLVector3 tangent = binormal % vd.mNormal;
-
- tc.mV[1] = -((tangent*vec)*2 - 0.5f);
-
- tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f;
-
- if (vd.mNormal.mV[1] < 0)
- {
- tc.mV[0] = 1.0f-tc.mV[0];
- }*/
-}
-
////////////////////
//
// LLFace implementation
@@ -167,8 +132,12 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
//special value to indicate uninitialized position
mIndicesIndex = 0xFFFFFFFF;
- mIndexInTex = 0;
- mTexture = NULL;
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ mIndexInTex[i] = 0;
+ mTexture[i] = NULL;
+ }
+
mTEOffset = -1;
mTextureIndex = 255;
@@ -185,8 +154,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mImportanceToCamera = 0.f ;
mBoundingSphereRadius = 0.0f ;
- mAtlasInfop = NULL ;
- mUsingAtlas = FALSE ;
mHasMedia = FALSE ;
}
@@ -197,9 +164,12 @@ void LLFace::destroy()
gPipeline.checkReferences(this);
}
- if(mTexture.notNull())
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
- mTexture->removeFace(this) ;
+ if(mTexture[i].notNull())
+ {
+ mTexture[i]->removeFace(i, this) ;
+ }
}
if (isState(LLFace::PARTICLE))
@@ -239,8 +209,7 @@ void LLFace::destroy()
}
setDrawInfo(NULL);
- removeAtlas();
-
+
mDrawablep = NULL;
mVObjp = NULL;
}
@@ -293,48 +262,76 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
setTexture(texturep) ;
}
-void LLFace::setTexture(LLViewerTexture* tex)
+void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
{
- if(mTexture == tex)
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mTexture[ch] == tex)
{
return ;
}
- if(mTexture.notNull())
+ if(mTexture[ch].notNull())
{
- mTexture->removeFace(this) ;
- removeAtlas() ;
+ mTexture[ch]->removeFace(ch, this) ;
}
if(tex)
{
- tex->addFace(this) ;
+ tex->addFace(ch, this) ;
}
- mTexture = tex ;
+ mTexture[ch] = tex ;
+}
+
+void LLFace::setTexture(LLViewerTexture* tex)
+{
+ setDiffuseMap(tex);
+}
+
+void LLFace::setDiffuseMap(LLViewerTexture* tex)
+{
+ setTexture(LLRender::DIFFUSE_MAP, tex);
+}
+
+void LLFace::setNormalMap(LLViewerTexture* tex)
+{
+ setTexture(LLRender::NORMAL_MAP, tex);
+}
+
+void LLFace::setSpecularMap(LLViewerTexture* tex)
+{
+ setTexture(LLRender::SPECULAR_MAP, tex);
}
void LLFace::dirtyTexture()
{
LLDrawable* drawablep = getDrawable();
- if (mVObjp.notNull() && mVObjp->getVolume() &&
- mTexture.notNull() && mTexture->getComponents() == 4)
- { //dirty texture on an alpha object should be treated as an LoD update
- LLVOVolume* vobj = drawablep->getVOVolume();
- if (vobj)
+ if (mVObjp.notNull() && mVObjp->getVolume())
+ {
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
- vobj->mLODChanged = TRUE;
+ if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
+ { //dirty texture on an alpha object should be treated as an LoD update
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj)
+ {
+ vobj->mLODChanged = TRUE;
+ }
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
+ }
}
- gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
- }
+ }
gPipeline.markTextured(drawablep);
}
-void LLFace::switchTexture(LLViewerTexture* new_texture)
+void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
{
- if(mTexture == new_texture)
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mTexture[ch] == new_texture)
{
return ;
}
@@ -344,10 +341,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture)
llerrs << "Can not switch to a null texture." << llendl;
return;
}
- new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
- getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
- setTexture(new_texture) ;
+ llassert(mTexture[ch].notNull());
+
+ new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
+
+ if (ch == LLRender::DIFFUSE_MAP)
+ {
+ getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
+ }
+
+ setTexture(ch, new_texture) ;
dirtyTexture();
}
@@ -543,7 +547,9 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
}
else
{
- mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+ // cheaters sometimes prosper...
+ //
+ mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask());
mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
}
@@ -811,6 +817,12 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
size.mul(scale);
}
+ // Catch potential badness from normalization before it happens
+ //
+ llassert(mat_normal.mMatrix[0].isFinite3() && (mat_normal.mMatrix[0].dot3(mat_normal.mMatrix[0]).getF32() > F_APPROXIMATELY_ZERO));
+ llassert(mat_normal.mMatrix[1].isFinite3() && (mat_normal.mMatrix[1].dot3(mat_normal.mMatrix[1]).getF32() > F_APPROXIMATELY_ZERO));
+ llassert(mat_normal.mMatrix[2].isFinite3() && (mat_normal.mMatrix[2].dot3(mat_normal.mMatrix[2]).getF32() > F_APPROXIMATELY_ZERO));
+
mat_normal.mMatrix[0].normalize3fast();
mat_normal.mMatrix[1].normalize3fast();
mat_normal.mMatrix[2].normalize3fast();
@@ -896,7 +908,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
// integrated with getGeometryVolume() for its texture coordinate
// generation - but i'll leave that to someone more familiar
// with the implications.
-LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal)
+LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal)
{
LLVector2 tc = surface_coord;
@@ -916,7 +928,9 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);
LLVector4a volume_position;
- volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV);
+ LLVector3 v_position(position.getF32ptr());
+
+ volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV);
if (!mDrawablep->getVOVolume()->isVolumeGlobal())
{
@@ -926,23 +940,14 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
}
LLVector4a volume_normal;
- volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV);
+ LLVector3 v_normal(normal.getF32ptr());
+ volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV);
volume_normal.normalize3fast();
- switch (texgen)
+ if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
{
- case LLTextureEntry::TEX_GEN_PLANAR:
planarProjection(tc, volume_normal, center, volume_position);
- break;
- case LLTextureEntry::TEX_GEN_SPHERICAL:
- sphericalProjection(tc, volume_normal, center, volume_position);
- break;
- case LLTextureEntry::TEX_GEN_CYLINDRICAL:
- cylindricalProjection(tc, volume_normal, center, volume_position);
- break;
- default:
- break;
- }
+ }
}
if (mTextureMatrix) // if we have a texture matrix, use it
@@ -969,7 +974,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& binormal4a = vf.mBinormals[0];
+ const LLVector4a& tangent = vf.mTangents[0];
+
+ LLVector4a binormal4a;
+ binormal4a.setCross3(normal4a, tangent);
+ binormal4a.mul(tangent.getF32ptr()[3]);
+
LLVector2 projected_binormal;
planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);
projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform()
@@ -1059,6 +1069,12 @@ bool LLFace::canRenderAsMask()
return false;
}
+ LLMaterial* mat = te->getMaterialParams();
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+ {
+ return false;
+ }
+
if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha
(te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask
getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive)
@@ -1091,7 +1107,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
{
LLFastTimer t(FTM_FACE_GEOM_VOLUME);
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL;
+ LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;
if (vf.mWeights)
{
@@ -1104,11 +1120,11 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
buff->allocateBuffer(vf.mNumVertices, 0, true);
LLStrider<LLVector4a> f_vert;
- LLStrider<LLVector3> f_binorm;
+ LLStrider<LLVector4a> f_tangent;
LLStrider<LLVector3> f_norm;
LLStrider<LLVector2> f_tc;
- buff->getBinormalStrider(f_binorm);
+ buff->getTangentStrider(f_tangent);
buff->getVertexStrider(f_vert);
buff->getNormalStrider(f_norm);
buff->getTexCoord0Strider(f_tc);
@@ -1116,7 +1132,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
for (U32 i = 0; i < vf.mNumVertices; ++i)
{
*f_vert++ = vf.mPositions[i];
- (*f_binorm++).set(vf.mBinormals[i].getF32ptr());
+ *f_tangent++ = vf.mTangents[i];
*f_tc++ = vf.mTexCoords[i];
(*f_norm++).set(vf.mNormals[i].getF32ptr());
}
@@ -1158,7 +1174,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights");
-static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TANGENT("Binormal");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail");
static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos");
@@ -1219,11 +1235,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
LLStrider<LLVector3> vert;
- LLStrider<LLVector2> tex_coords;
+ LLStrider<LLVector2> tex_coords0;
+ LLStrider<LLVector2> tex_coords1;
LLStrider<LLVector2> tex_coords2;
LLStrider<LLVector3> norm;
LLStrider<LLColor4U> colors;
- LLStrider<LLVector3> binorm;
+ LLStrider<LLVector3> tangent;
LLStrider<U16> indicesp;
LLStrider<LLVector4> wght;
@@ -1245,33 +1262,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
- bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL);
+ bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);
bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);
const LLTextureEntry *tep = mVObjp->getTE(f);
const U8 bump_code = tep ? tep->getBumpmap() : 0;
- F32 tcoord_xoffset = 0.f ;
- F32 tcoord_yoffset = 0.f ;
- F32 tcoord_xscale = 1.f ;
- F32 tcoord_yscale = 1.f ;
- BOOL in_atlas = FALSE ;
-
- if (rebuild_tcoord)
- {
- in_atlas = isAtlasInUse() ;
- if(in_atlas)
- {
- const LLVector2* tmp = getTexCoordOffset() ;
- tcoord_xoffset = tmp->mV[0] ;
- tcoord_yoffset = tmp->mV[1] ;
-
- tmp = getTexCoordScale() ;
- tcoord_xscale = tmp->mV[0] ;
- tcoord_yscale = tmp->mV[1] ;
- }
- }
-
BOOL is_static = mDrawablep->isStatic();
BOOL is_global = is_static;
@@ -1289,19 +1285,41 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLColor4U color = tep->getColor();
if (rebuild_color)
- {
- if (tep)
+ { //decide if shiny goes in alpha channel of color
+ if (tep &&
+ getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
{
- GLfloat alpha[4] =
- {
- 0.00f,
- 0.25f,
- 0.5f,
- 0.75f
- };
+ LLMaterial* mat = tep->getMaterialParams().get();
+
+ bool shiny_in_alpha = false;
- if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny())))
+ if (LLPipeline::sRenderDeferred)
+ { //store shiny in alpha if we don't have a specular map
+ if (!mat || mat->getSpecularID().isNull())
+ {
+ shiny_in_alpha = true;
+ }
+ }
+ else
{
+ if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ shiny_in_alpha = true;
+ }
+ }
+
+ if (shiny_in_alpha)
+ {
+
+ GLfloat alpha[4] =
+ {
+ 0.00f,
+ 0.25f,
+ 0.5f,
+ 0.75f
+ };
+
+ llassert(tep->getShiny() <= 3);
color.mV[3] = U8 (alpha[tep->getShiny()] * 255);
}
}
@@ -1392,7 +1410,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
{
- mVObjp->getVolume()->genBinormals(f);
+ mVObjp->getVolume()->genTangents(f);
LLFace::cacheFaceInVRAM(vf);
buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
}
@@ -1477,15 +1495,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
glEndTransformFeedback();
}
- if (rebuild_binormal)
+ if (rebuild_tangent)
{
- LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
- gTransformBinormalProgram.bind();
+ LLFastTimer t(FTM_FACE_GEOM_TANGENT);
+ gTransformTangentProgram.bind();
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount);
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);
glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_BINORMAL);
+ buff->setBuffer(LLVertexBuffer::MAP_TANGENT);
push_for_transform(buff, vf.mNumVertices, mGeomCount);
glEndTransformFeedback();
}
@@ -1547,7 +1565,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (bump_code)
{
- mVObjp->getVolume()->genBinormals(f);
+ mVObjp->getVolume()->genTangents(f);
F32 offset_multiple;
switch( bump_code )
{
@@ -1556,11 +1574,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
- if( mTexture.notNull() && mTexture->hasGLTexture())
+ if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())
{
// Offset by approximately one texel
- S32 cur_discard = mTexture->getDiscardLevel();
- S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
+ S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel();
+ S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );
max_size <<= cur_discard;
const F32 ARTIFICIAL_OFFSET = 2.f;
offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
@@ -1596,16 +1614,23 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
U8 texgen = getTextureEntry()->getTexGen();
if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{ //planar texgen needs binormals
- mVObjp->getVolume()->genBinormals(f);
+ mVObjp->getVolume()->genTangents(f);
}
U8 tex_mode = 0;
+ bool tex_anim = false;
+
+ LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
+ tex_mode = vobj->mTexAnimMode;
+
+ if (vobj->mTextureAnimp)
+ { //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
+ tex_anim = true;
+ }
+
if (isState(TEXTURE_ANIM))
{
- LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
- tex_mode = vobj->mTexAnimMode;
-
if (!tex_mode)
{
clearState(TEXTURE_ANIM);
@@ -1620,7 +1645,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
do_xform = false;
}
-
+
if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
{ //don't override texture transform during tc bake
tex_mode = 0;
@@ -1630,12 +1655,21 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a scalea;
scalea.load3(scale.mV);
+ LLMaterial* mat = tep->getMaterialParams().get();
+
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- bool do_tex_mat = tex_mode && mTextureMatrix;
- if (!in_atlas && !do_bump)
- { //not in atlas or not bump mapped, might be able to do a cheap update
- mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
+ if (mat && !do_bump)
+ {
+ do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
+ || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
+ }
+
+ bool do_tex_mat = tex_mode && mTextureMatrix;
+
+ if (!do_bump)
+ { //not bump mapped, might be able to do a cheap update
+ mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount);
if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
{
@@ -1646,12 +1680,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
- LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size);
+ LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size);
}
else
{
LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
- F32* dst = (F32*) tex_coords.get();
+ F32* dst = (F32*) tex_coords0.get();
LLVector4a* src = (LLVector4a*) vf.mTexCoords;
LLVector4a trans;
@@ -1686,7 +1720,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
else
- { //do tex mat, no texgen, no atlas, no bump
+ { //do tex mat, no texgen, no bump
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
@@ -1697,12 +1731,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
- *tex_coords++ = tc;
+ *tex_coords0++ = tc;
}
}
}
else
- { //no bump, no atlas, tex gen planar
+ { //no bump, tex gen planar
LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
if (do_tex_mat)
{
@@ -1720,7 +1754,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
- *tex_coords++ = tc;
+ *tex_coords0++ = tc;
}
}
else
@@ -1736,7 +1770,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
- *tex_coords++ = tc;
+ *tex_coords0++ = tc;
}
}
}
@@ -1747,145 +1781,104 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
else
- { //either bump mapped or in atlas, just do the whole expensive loop
+ { //bump mapped or has material, just do the whole expensive loop
LLFastTimer t(FTM_FACE_TEX_DEFAULT);
- mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);
-
- std::vector<LLVector2> bump_tc;
-
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
-
- LLVector4a& norm = vf.mNormals[i];
-
- LLVector4a& center = *(vf.mCenter);
-
- if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- {
- LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
+ std::vector<LLVector2> bump_tc;
- switch (texgen)
- {
- case LLTextureEntry::TEX_GEN_PLANAR:
- planarProjection(tc, norm, center, vec);
- break;
- case LLTextureEntry::TEX_GEN_SPHERICAL:
- sphericalProjection(tc, norm, center, vec);
- break;
- case LLTextureEntry::TEX_GEN_CYLINDRICAL:
- cylindricalProjection(tc, norm, center, vec);
- break;
- default:
- break;
- }
- }
+ if (mat && !mat->getNormalID().isNull())
+ { //writing out normal and specular texture coordinates, not bump offsets
+ do_bump = false;
+ }
- if (tex_mode && mTextureMatrix)
- {
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
- }
- else
- {
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
- }
+ LLStrider<LLVector2> dst;
- if(in_atlas)
+ for (U32 ch = 0; ch < 3; ++ch)
+ {
+ switch (ch)
{
- //
- //manually calculate tex-coord per vertex for varying address modes.
- //should be removed if shader can handle this.
- //
-
- S32 int_part = 0 ;
- switch(mTexture->getAddressMode())
- {
- case LLTexUnit::TAM_CLAMP:
- if(tc.mV[0] < 0.f)
- {
- tc.mV[0] = 0.f ;
- }
- else if(tc.mV[0] > 1.f)
- {
- tc.mV[0] = 1.f;
- }
-
- if(tc.mV[1] < 0.f)
- {
- tc.mV[1] = 0.f ;
- }
- else if(tc.mV[1] > 1.f)
- {
- tc.mV[1] = 1.f;
- }
+ case 0:
+ mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
break;
- case LLTexUnit::TAM_MIRROR:
- if(tc.mV[0] < 0.f)
- {
- tc.mV[0] = -tc.mV[0] ;
- }
- int_part = (S32)tc.mV[0] ;
- if(int_part & 1) //odd number
- {
- tc.mV[0] = int_part + 1 - tc.mV[0] ;
- }
- else //even number
+ case 1:
+ if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
{
- tc.mV[0] -= int_part ;
- }
+ mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range);
+ if (mat && !tex_anim)
+ {
+ r = mat->getNormalRotation();
+ mat->getNormalOffset(os, ot);
+ mat->getNormalRepeat(ms, mt);
- if(tc.mV[1] < 0.f)
- {
- tc.mV[1] = -tc.mV[1] ;
- }
- int_part = (S32)tc.mV[1] ;
- if(int_part & 1) //odd number
- {
- tc.mV[1] = int_part + 1 - tc.mV[1] ;
+ cos_ang = cos(r);
+ sin_ang = sin(r);
+
+ }
}
- else //even number
+ else
{
- tc.mV[1] -= int_part ;
+ continue;
}
break;
- case LLTexUnit::TAM_WRAP:
- if(tc.mV[0] > 1.f)
- tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ;
- else if(tc.mV[0] < -1.f)
- tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ;
-
- if(tc.mV[1] > 1.f)
- tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ;
- else if(tc.mV[1] < -1.f)
- tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ;
-
- if(tc.mV[0] < 0.f)
+ case 2:
+ if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
{
- tc.mV[0] = 1.0f + tc.mV[0] ;
+ mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range);
+ if (mat && !tex_anim)
+ {
+ r = mat->getSpecularRotation();
+ mat->getSpecularOffset(os, ot);
+ mat->getSpecularRepeat(ms, mt);
+
+ cos_ang = cos(r);
+ sin_ang = sin(r);
+ }
}
- if(tc.mV[1] < 0.f)
+ else
{
- tc.mV[1] = 1.0f + tc.mV[1] ;
+ continue;
}
break;
- default:
- break;
- }
-
- tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
- tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
}
+
+
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+
+ LLVector4a& norm = vf.mNormals[i];
+
+ LLVector4a& center = *(vf.mCenter);
+
+ if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ {
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
- *tex_coords++ = tc;
- if (do_bump)
- {
- bump_tc.push_back(tc);
+ if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
+ {
+ planarProjection(tc, norm, center, vec);
+ }
+ }
+
+ if (tex_mode && mTextureMatrix)
+ {
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
+ }
+ else
+ {
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ }
+
+ *dst++ = tc;
+ if (do_bump)
+ {
+ bump_tc.push_back(tc);
+ }
}
}
@@ -1894,17 +1887,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->flush();
}
- if (do_bump)
+ if (!mat && do_bump)
{
- mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
for (S32 i = 0; i < num_vertices; i++)
{
- LLVector4a tangent;
- tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]);
+ LLVector4a tangent = vf.mTangents[i];
+ LLVector4a binorm;
+ binorm.setCross3(vf.mNormals[i], tangent);
+ binorm.mul(tangent.getF32ptr()[3]);
+
LLMatrix4a tangent_to_object;
- tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]);
+ tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);
LLVector4a t;
tangent_to_object.rotate(binormal_dir, t);
LLVector4a binormal;
@@ -1920,10 +1916,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
binormal.normalize3fast();
+
LLVector2 tc = bump_tc[i];
tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
- *tex_coords2++ = tc;
+ *tex_coords1++ = tc;
}
if (map_range)
@@ -2006,7 +2003,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLFastTimer t(FTM_FACE_GEOM_NORMAL);
mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
F32* normals = (F32*) norm.get();
-
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a normal;
@@ -2022,19 +2018,27 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
- if (rebuild_binormal)
+ if (rebuild_tangent)
{
- LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
- mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
- F32* binormals = (F32*) binorm.get();
-
+ LLFastTimer t(FTM_FACE_GEOM_TANGENT);
+ mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
+ F32* tangents = (F32*) tangent.get();
+
+ mVObjp->getVolume()->genTangents(f);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector4a binormal;
- mat_normal.rotate(vf.mBinormals[i], binormal);
- binormal.normalize3fast();
- binormal.store4a(binormals);
- binormals += 4;
+ {
+ LLVector4a tangent_out;
+ mat_normal.rotate(vf.mTangents[i], tangent_out);
+ tangent_out.normalize3fast();
+ tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out);
+ tangent_out.store4a(tangents);
+
+ tangents += 4;
}
if (map_range)
@@ -2097,11 +2101,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a src;
- U32 glow32 = glow |
- (glow << 8) |
- (glow << 16) |
- (glow << 24);
+ LLColor4U glow4u = LLColor4U(0,0,0,glow);
+ U32 glow32 = glow4u.mAll;
+
U32 vec[4];
vec[0] = vec[1] = vec[2] = vec[3] = glow32;
@@ -2153,9 +2156,9 @@ BOOL LLFace::hasMedia() const
{
return TRUE ;
}
- if(mTexture.notNull())
+ if(mTexture[LLRender::DIFFUSE_MAP].notNull())
{
- return mTexture->hasParcelMedia() ; //if has a parcel media
+ return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media
}
return FALSE ; //no media.
@@ -2207,7 +2210,7 @@ F32 LLFace::getTextureVirtualSize()
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ;
if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
{
- if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage())
+ if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
{
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
}
@@ -2246,7 +2249,7 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
dist *= 16.f;
}
- lookAt.normalize3fast() ;
+ lookAt.normalize3fast();
//get area of circle around node
F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
@@ -2574,159 +2577,13 @@ LLVector3 LLFace::getPositionAgent() const
}
}
-//
-//atlas
-//
-void LLFace::removeAtlas()
-{
- setAtlasInUse(FALSE) ;
- mAtlasInfop = NULL ;
-}
-
-const LLTextureAtlas* LLFace::getAtlas()const
-{
- if(mAtlasInfop)
- {
- return mAtlasInfop->getAtlas() ;
- }
- return NULL ;
-}
-
-const LLVector2* LLFace::getTexCoordOffset()const
-{
- if(isAtlasInUse())
- {
- return mAtlasInfop->getTexCoordOffset() ;
- }
- return NULL ;
-}
-const LLVector2* LLFace::getTexCoordScale() const
-{
- if(isAtlasInUse())
- {
- return mAtlasInfop->getTexCoordScale() ;
- }
- return NULL ;
-}
-
-BOOL LLFace::isAtlasInUse()const
-{
- return mUsingAtlas ;
-}
-
-BOOL LLFace::canUseAtlas()const
+LLViewerTexture* LLFace::getTexture(U32 ch) const
{
- //no drawable or no spatial group, do not use atlas
- if(!mDrawablep || !mDrawablep->getSpatialGroup())
- {
- return FALSE ;
- }
-
- //if bump face, do not use atlas
- if(getTextureEntry() && getTextureEntry()->getBumpmap())
- {
- return FALSE ;
- }
-
- //if animated texture, do not use atlas
- if(isState(TEXTURE_ANIM))
- {
- return FALSE ;
- }
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
- return TRUE ;
-}
-
-void LLFace::setAtlasInUse(BOOL flag)
-{
- //no valid atlas to use.
- if(flag && (!mAtlasInfop || !mAtlasInfop->isValid()))
- {
- flag = FALSE ;
- }
-
- if(!flag && !mUsingAtlas)
- {
- return ;
- }
-
- //
- //at this stage (flag || mUsingAtlas) is always true.
- //
-
- //rebuild the tex coords
- if(mDrawablep)
- {
- gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD);
- mUsingAtlas = flag ;
- }
- else
- {
- mUsingAtlas = FALSE ;
- }
+ return mTexture[ch] ;
}
-LLTextureAtlasSlot* LLFace::getAtlasInfo()
-{
- return mAtlasInfop ;
-}
-
-void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp)
-{
- if(mAtlasInfop != atlasp)
- {
- if(mAtlasInfop)
- {
- //llerrs << "Atlas slot changed!" << llendl ;
- }
- mAtlasInfop = atlasp ;
- }
-}
-
-LLViewerTexture* LLFace::getTexture() const
-{
- if(isAtlasInUse())
- {
- return (LLViewerTexture*)mAtlasInfop->getAtlas() ;
- }
-
- return mTexture ;
-}
-
-//switch to atlas or switch back to gl texture
-//return TRUE if using atlas.
-BOOL LLFace::switchTexture()
-{
- //no valid atlas or texture
- if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture)
- {
- return FALSE ;
- }
-
- if(mTexture->getTexelsInAtlas() >= (U32)mVSize ||
- mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture())
- {
- //switch to use atlas
- //atlas resolution is qualified, use it.
- if(!mUsingAtlas)
- {
- setAtlasInUse(TRUE) ;
- }
- }
- else //if atlas not qualified.
- {
- //switch back to GL texture
- if(mUsingAtlas && mTexture->isGLTextureCreated() &&
- mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas())
- {
- setAtlasInUse(FALSE) ;
- }
- }
-
- return mUsingAtlas ;
-}
-
-
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
{
mVertexBuffer = buffer;
@@ -2742,6 +2599,22 @@ void LLFace::clearVertexBuffer()
U32 LLFace::getRiggedDataMask(U32 type)
{
static const U32 rigged_data_mask[] = {
+ LLDrawPoolAvatar::RIGGED_MATERIAL_MASK,
+ LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK,
+ LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK,
+ LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK,
+ LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK,
+ LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK,
+ LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK,
+ LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK,
+ LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK,
+ LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_SIMPLE_MASK,
LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK,
LLDrawPoolAvatar::RIGGED_SHINY_MASK,
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index de4d03351c..0687544d53 100755
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -41,7 +41,6 @@
#include "llvertexbuffer.h"
#include "llviewertexture.h"
#include "lldrawable.h"
-#include "lltextureatlasmanager.h"
class LLFacePool;
class LLVolume;
@@ -50,7 +49,6 @@ class LLTextureEntry;
class LLVertexProgram;
class LLViewerTexture;
class LLGeometryManager;
-class LLTextureAtlasSlot;
const F32 MIN_ALPHA_SIZE = 1024.f;
const F32 MIN_TEX_ANIM_SIZE = 512.f;
@@ -110,13 +108,17 @@ public:
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
void setTextureIndex(U8 index);
U8 getTextureIndex() const { return mTextureIndex; }
+ void setTexture(U32 ch, LLViewerTexture* tex);
void setTexture(LLViewerTexture* tex) ;
- void switchTexture(LLViewerTexture* new_texture);
+ void setDiffuseMap(LLViewerTexture* tex);
+ void setNormalMap(LLViewerTexture* tex);
+ void setSpecularMap(LLViewerTexture* tex);
+ void switchTexture(U32 ch, LLViewerTexture* new_texture);
void dirtyTexture();
LLXformMatrix* getXform() const { return mXform; }
BOOL hasGeometry() const { return mGeomCount > 0; }
LLVector3 getPositionAgent() const;
- LLVector2 surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal);
+ LLVector2 surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);
void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;
bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,
LLVector2* st_scale, F32* st_rot) const;
@@ -130,8 +132,8 @@ public:
F32 getVirtualSize() const { return mVSize; }
F32 getPixelArea() const { return mPixelArea; }
- S32 getIndexInTex() const {return mIndexInTex ;}
- void setIndexInTex(S32 index) { mIndexInTex = index ;}
+ S32 getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];}
+ void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index ;}
void renderSetColor() const;
S32 renderElements(const U16 *index_array) const;
@@ -149,7 +151,7 @@ public:
S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; }
void setPoolType(U32 type) { mPoolType = type; }
S32 getTEOffset() { return mTEOffset; }
- LLViewerTexture* getTexture() const;
+ LLViewerTexture* getTexture(U32 ch = LLRender::DIFFUSE_MAP) const;
void setViewerObject(LLViewerObject* object);
void setPool(LLFacePool *pool, LLViewerTexture *texturep);
@@ -223,16 +225,6 @@ public:
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
BOOL hasMedia() const ;
- //for atlas
- LLTextureAtlasSlot* getAtlasInfo() ;
- void setAtlasInUse(BOOL flag);
- void setAtlasInfo(LLTextureAtlasSlot* atlasp);
- BOOL isAtlasInUse()const;
- BOOL canUseAtlas() const;
- const LLVector2* getTexCoordScale() const ;
- const LLVector2* getTexCoordOffset()const;
- const LLTextureAtlas* getAtlas()const ;
- void removeAtlas() ;
BOOL switchTexture() ;
//vertex buffer tracking
@@ -266,6 +258,8 @@ public:
F32 mLastSkinTime;
F32 mLastMoveTime;
LLMatrix4* mTextureMatrix;
+ LLMatrix4* mSpecMapMatrix;
+ LLMatrix4* mNormalMapMatrix;
LLDrawInfo* mDrawInfo;
private:
@@ -281,10 +275,12 @@ private:
U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing
U32 mIndicesCount;
U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
- S32 mIndexInTex ;
+ S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];
LLXformMatrix* mXform;
- LLPointer<LLViewerTexture> mTexture;
+
+ LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS];
+
LLPointer<LLDrawable> mDrawablep;
LLPointer<LLViewerObject> mVObjp;
S32 mTEOffset;
@@ -302,9 +298,6 @@ private:
F32 mBoundingSphereRadius ;
bool mHasMedia ;
- //atlas
- LLPointer<LLTextureAtlasSlot> mAtlasInfop ;
- BOOL mUsingAtlas ;
protected:
static BOOL sSafeRenderSelect;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 58817485fb..b40789db9c 100755
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -2021,7 +2021,7 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
{
LLMultiFloater::setMinimized(FALSE);
}
-
+
LLFloater::closeFloater(app_quitting);
}
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 49f36a2f32..56b0c15cb9 100755
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -328,7 +328,7 @@ void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)
void LLFloaterIMNearbyChat::show()
{
openFloater(getKey());
-}
+ }
bool LLFloaterIMNearbyChat::isChatVisible() const
{
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index bbf88060c1..55b03986d0 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1089,8 +1089,9 @@ void LLFloaterPreference::refreshEnabledState()
ctrl_reflections->setEnabled(reflections);
// Bump & Shiny
+ LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
- getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE);
+ bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
radio_reflection_detail->setEnabled(reflections);
@@ -1148,7 +1149,8 @@ void LLFloaterPreference::refreshEnabledState()
//Deferred/SSAO/Shadows
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
- BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
shaders &&
gGLManager.mHasFramebufferObject &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
@@ -1161,7 +1163,9 @@ void LLFloaterPreference::refreshEnabledState()
LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
-
+
+ ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
+
ctrl_ssao->setEnabled(enabled);
ctrl_dof->setEnabled(enabled);
@@ -2319,3 +2323,4 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()
}
}
+
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 0ce0534802..a6be604222 100755
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -521,7 +521,7 @@ public:
void fire(const LLUUID& inv_item_id)
{
LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
-
+
if (item)
LLFriendCardsManager::instance().extractAvatarID(item->getCreatorUUID());
}
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 5eaa83d872..08e209c847 100755
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -166,7 +166,7 @@ void LLGestureMgr::activateGestures(LLViewerInventoryItem::item_array_t& items)
continue;
}
else
- { // Make gesture active and persistent through login sessions. -spatters 07-12-06
+ { // Make gesture active and persistent through login sessions. -Aura 07-12-06
activateGesture(item->getUUID());
}
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 7e1025c41b..825c2b31be 100755
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -202,7 +202,7 @@ void LLHUDIcon::render()
renderIcon(FALSE);
}
-BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection)
+BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
if (mHidden)
return FALSE;
@@ -275,23 +275,18 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
LLVector4a upper_right;
upper_right.setAdd(lower_right, y_scalea);
- LLVector4a enda;
- enda.load3(end.mV);
- LLVector4a starta;
- starta.load3(start.mV);
LLVector4a dir;
- dir.setSub(enda, starta);
+ dir.setSub(end, start);
F32 a,b,t;
- if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, a,b,t) ||
- LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, a,b,t))
+ if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, a,b,t) ||
+ LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, a,b,t))
{
if (intersection)
{
dir.mul(t);
- starta.add(dir);
- *intersection = LLVector3(starta.getF32ptr());
+ intersection->setAdd(start, dir);
}
return TRUE;
}
@@ -331,12 +326,12 @@ LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)
}
//static
-LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection)
+LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
icon_instance_t::iterator icon_it;
- LLVector3 local_end = end;
- LLVector3 position;
+ LLVector4a local_end = end;
+ LLVector4a position;
LLHUDIcon* ret = NULL;
for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h
index 644daa0299..557252ab0b 100755
--- a/indra/newview/llhudicon.h
+++ b/indra/newview/llhudicon.h
@@ -62,7 +62,7 @@ public:
static S32 generatePickIDs(S32 start_id, S32 step_size);
static LLHUDIcon* handlePick(S32 pick_id);
- static LLHUDIcon* lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection);
+ static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
static void updateAll();
static void cleanupDeadIcons();
@@ -73,7 +73,7 @@ public:
BOOL getHidden() const { return mHidden; }
void setHidden( BOOL hide ) { mHidden = hide; }
- BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection);
+ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
protected:
LLHUDIcon(const U8 type);
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 3336097955..c3b49f739a 100755
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -116,7 +116,7 @@ LLHUDNameTag::~LLHUDNameTag()
}
-BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render)
+BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render)
{
if (!mVisible || mHidden)
{
@@ -199,15 +199,23 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
bg_pos + height_vec,
};
- LLVector3 dir = end-start;
+ LLVector4a dir;
+ dir.setSub(end,start);
F32 a, b, t;
- if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
- LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+ LLVector4a v0,v1,v2,v3;
+ v0.load3(v[0].mV);
+ v1.load3(v[1].mV);
+ v2.load3(v[2].mV);
+ v3.load3(v[3].mV);
+
+ if (LLTriangleRayIntersect(v0, v1, v2, start, dir, a, b, t) ||
+ LLTriangleRayIntersect(v2, v3, v0, start, dir, a, b, t) )
{
if (t <= 1.f)
{
- intersection = start + dir*t;
+ dir.mul(t);
+ intersection.setAdd(start, dir);
return TRUE;
}
}
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 72647d5b26..38a4f18415 100755
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -124,7 +124,7 @@ public:
void setHidden( BOOL hide ) { mHidden = hide; }
void shift(const LLVector3& offset);
- BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE);
+ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render = FALSE);
static void shiftAll(const LLVector3& offset);
static void addPickable(std::set<LLViewerObject*> &pick_list);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 0481bf5f45..c9fe2127fe 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3335,7 +3335,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
}
- //Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06
+ //Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06
mCallingCards = mWearables = FALSE;
LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 25df4889b0..2d9385390b 100755
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -58,6 +58,8 @@
#include "lltexlayerparams.h"
#include "llvovolume.h"
#include "llnotificationsutil.h"
+#include "pipeline.h"
+#include "llmaterialmgr.h"
/*=======================================*/
/* Formal declarations, constants, etc. */
@@ -339,7 +341,12 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
return;
}
- updateUserPrims(old_id, new_id);
+ // processing updates per channel; makes the process scalable.
+ // the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc.
+ updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP);
+ updateUserPrims(old_id, new_id, LLRender::NORMAL_MAP);
+ updateUserPrims(old_id, new_id, LLRender::SPECULAR_MAP);
+
updateUserSculpts(old_id, new_id); // isn't there supposed to be an IMG_DEFAULT_SCULPT or something?
// default safeguard image for layers
@@ -367,15 +374,15 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
// this function sorts the faces from a getFaceList[getNumFaces] into a list of objects
// in order to prevent multiple sendTEUpdate calls per object during updateUserPrims
-std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id)
+std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32 channel)
{
std::vector<LLViewerObject*> obj_list;
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id);
-
- for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(); face_iterator++)
+
+ for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)
{
// getting an object from a face
- LLFace* face_to_object = (*old_texture->getFaceList())[face_iterator];
+ LLFace* face_to_object = (*old_texture->getFaceList(channel))[face_iterator];
if(face_to_object)
{
@@ -416,9 +423,9 @@ std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id)
return obj_list;
}
-void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)
+void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)
{
- std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id);
+ std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id, channel);
for(std::vector<LLViewerObject*>::iterator object_iterator = objectlist.begin();
object_iterator != objectlist.end(); object_iterator++)
@@ -427,7 +434,8 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)
if(object)
{
- bool update_obj = false;
+ bool update_tex = false;
+ bool update_mat = false;
S32 num_faces = object->getNumFaces();
for (U8 face_iter = 0; face_iter < num_faces; face_iter++)
@@ -435,20 +443,51 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)
if (object->mDrawable)
{
LLFace* face = object->mDrawable->getFace(face_iter);
- if (face && face->getTexture() && face->getTexture()->getID() == old_id)
+ if (face && face->getTexture(channel) && face->getTexture(channel)->getID() == old_id)
{
- object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture(
- new_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ // these things differ per channel, unless there already is a universal
+ // texture setting function to setTE that takes channel as a param?
+ // p.s.: switch for now, might become if - if an extra test is needed to verify before touching normalmap/specmap
+ switch(channel)
+ {
+ case LLRender::DIFFUSE_MAP:
+ {
+ object->setTETexture(face_iter, new_id);
+ update_tex = true;
+ break;
+ }
+
+ case LLRender::NORMAL_MAP:
+ {
+ object->setTENormalMap(face_iter, new_id);
+ update_mat = true;
+ update_tex = true;
+ break;
+ }
+
+ case LLRender::SPECULAR_MAP:
+ {
+ object->setTESpecularMap(face_iter, new_id);
+ update_mat = true;
+ update_tex = true;
+ break;
+ }
+ }
+ // end switch
- update_obj = true;
}
}
}
- if (update_obj)
+ if (update_tex)
{
object->sendTEUpdate();
}
+
+ if (update_mat)
+ {
+ object->mDrawable->getVOVolume()->faceMappingChanged();
+ }
}
}
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index 580b6dfa7e..2ee84bf46e 100755
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -62,8 +62,8 @@ class LLLocalBitmap
private: /* self update private section */
bool decodeBitmap(LLPointer<LLImageRaw> raw);
void replaceIDs(LLUUID old_id, LLUUID new_id);
- std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id);
- void updateUserPrims(LLUUID old_id, LLUUID new_id);
+ std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id, U32 channel);
+ void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);
void updateUserSculpts(LLUUID old_id, LLUUID new_id);
void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);
LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 977c50682f..f681c12747 100755
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -642,6 +642,8 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event)
void LLLoginInstance::handleLoginFailure(const LLSD& event)
{
+
+
// Login has failed.
// Figure out why and respond...
LLSD response = event["data"];
@@ -654,10 +656,13 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
// to reconnect or to end the attempt in failure.
if(reason_response == "tos")
{
+ llinfos << "LLLoginInstance::handleLoginFailure ToS" << llendl;
+
LLSD data(LLSD::emptyMap());
data["message"] = message_response;
data["reply_pump"] = TOS_REPLY_PUMP;
- gViewerWindow->setShowProgress(FALSE);
+ if (gViewerWindow)
+ gViewerWindow->setShowProgress(FALSE);
LLFloaterReg::showInstance("message_tos", data);
LLEventPumps::instance().obtain(TOS_REPLY_PUMP)
.listen(TOS_LISTENER_NAME,
@@ -666,6 +671,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
}
else if(reason_response == "critical")
{
+ llinfos << "LLLoginInstance::handleLoginFailure Crit" << llendl;
+
LLSD data(LLSD::emptyMap());
data["message"] = message_response;
data["reply_pump"] = TOS_REPLY_PUMP;
@@ -678,7 +685,9 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
data["certificate"] = response["certificate"];
}
- gViewerWindow->setShowProgress(FALSE);
+ if (gViewerWindow)
+ gViewerWindow->setShowProgress(FALSE);
+
LLFloaterReg::showInstance("message_critical", data);
LLEventPumps::instance().obtain(TOS_REPLY_PUMP)
.listen(TOS_LISTENER_NAME,
@@ -687,21 +696,28 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
}
else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate"))
{
+ llinfos << "LLLoginInstance::handleLoginFailure update" << llendl;
+
gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);
updateApp(true, message_response);
}
else if(reason_response == "optional")
{
+ llinfos << "LLLoginInstance::handleLoginFailure optional" << llendl;
+
updateApp(false, message_response);
}
else
{
+ llinfos << "LLLoginInstance::handleLoginFailure attemptComplete" << llendl;
attemptComplete();
}
}
void LLLoginInstance::handleLoginSuccess(const LLSD& event)
{
+ llinfos << "LLLoginInstance::handleLoginSuccess" << llendl;
+
if(gSavedSettings.getBOOL("ForceMandatoryUpdate"))
{
LLSD response = event["data"];
@@ -723,6 +739,8 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event)
void LLLoginInstance::handleDisconnect(const LLSD& event)
{
// placeholder
+
+ llinfos << "LLLoginInstance::handleDisconnect placeholder " << llendl;
}
void LLLoginInstance::handleIndeterminate(const LLSD& event)
@@ -731,10 +749,13 @@ void LLLoginInstance::handleIndeterminate(const LLSD& event)
// gave the viewer a new url and params to try.
// The login module handles the retry, but it gives us the
// server response so that we may show
- // the user some status.
+ // the user some status.
+
LLSD message = event.get("data").get("message");
if(message.isDefined())
{
+ llinfos << "LLLoginInstance::handleIndeterminate " << message.asString() << llendl;
+
LLSD progress_update;
progress_update["desc"] = message;
LLEventPumps::getInstance()->obtain("LLProgressView").post(progress_update);
@@ -745,12 +766,16 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
{
if(accepted)
{
+ llinfos << "LLLoginInstance::handleTOSResponse: accepted" << llendl;
+
// Set the request data to true and retry login.
mRequestData["params"][key] = true;
reconnect();
}
else
{
+ llinfos << "LLLoginInstance::handleTOSResponse: attemptComplete" << llendl;
+
attemptComplete();
}
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
new file mode 100644
index 0000000000..16871adc4d
--- /dev/null
+++ b/indra/newview/llmaterialmgr.cpp
@@ -0,0 +1,782 @@
+/**
+ * @file llmaterialmgr.cpp
+ * @brief Material manager
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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 "llsdserialize.h"
+#include "llsdutil.h"
+
+#include "llagent.h"
+#include "llcallbacklist.h"
+#include "llmaterialmgr.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "llworld.h"
+
+/**
+ * Materials cap parameters
+ */
+
+#define MATERIALS_CAPABILITY_NAME "RenderMaterials"
+
+#define MATERIALS_CAP_ZIP_FIELD "Zipped"
+
+#define MATERIALS_CAP_FULL_PER_FACE_FIELD "FullMaterialsPerFace"
+#define MATERIALS_CAP_FACE_FIELD "Face"
+#define MATERIALS_CAP_MATERIAL_FIELD "Material"
+#define MATERIALS_CAP_OBJECT_ID_FIELD "ID"
+#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
+
+#define MATERIALS_GET_MAX_ENTRIES 50
+#define MATERIALS_GET_TIMEOUT (60.f * 20)
+#define MATERIALS_POST_MAX_ENTRIES 50
+#define MATERIALS_POST_TIMEOUT (60.f * 5)
+#define MATERIALS_PUT_THROTTLE_SECS 1.f
+#define MATERIALS_PUT_MAX_ENTRIES 50
+
+/**
+ * LLMaterialsResponder helper class
+ */
+
+class LLMaterialsResponder : public LLHTTPClient::Responder
+{
+public:
+ typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+
+ LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback);
+ virtual ~LLMaterialsResponder();
+
+ virtual void result(const LLSD& pContent);
+ virtual void error(U32 pStatus, const std::string& pReason);
+
+private:
+ std::string mMethod;
+ std::string mCapabilityURL;
+ CallbackFunction mCallback;
+};
+
+LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback)
+ : LLHTTPClient::Responder()
+ , mMethod(pMethod)
+ , mCapabilityURL(pCapabilityURL)
+ , mCallback(pCallback)
+{
+}
+
+LLMaterialsResponder::~LLMaterialsResponder()
+{
+}
+
+void LLMaterialsResponder::result(const LLSD& pContent)
+{
+ LL_DEBUGS("Materials") << LL_ENDL;
+ mCallback(true, pContent);
+}
+
+void LLMaterialsResponder::error(U32 pStatus, const std::string& pReason)
+{
+ LL_WARNS("Materials")
+ << "\n--------------------------------------------------------------------------\n"
+ << mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
+ << "'\n with url '" << mCapabilityURL << "' because " << pReason
+ << "\n--------------------------------------------------------------------------"
+ << LL_ENDL;
+
+ LLSD emptyResult;
+ mCallback(false, emptyResult);
+}
+
+/**
+ * LLMaterialMgr class
+ */
+
+LLMaterialMgr::LLMaterialMgr()
+{
+ mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(LLMaterialID::null, LLMaterialPtr(NULL)));
+ gIdleCallbacks.addFunction(&LLMaterialMgr::onIdle, NULL);
+ LLWorld::instance().setRegionRemovedCallback(boost::bind(&LLMaterialMgr::onRegionRemoved, this, _1));
+}
+
+LLMaterialMgr::~LLMaterialMgr()
+{
+ gIdleCallbacks.deleteFunction(&LLMaterialMgr::onIdle, NULL);
+}
+
+bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const
+{
+ get_pending_map_t::const_iterator itPending = mGetPending.find(pending_material_t(region_id, material_id));
+ return (mGetPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_POST_TIMEOUT);
+}
+
+void LLMaterialMgr::markGetPending(const LLUUID& region_id, const LLMaterialID& material_id)
+{
+ get_pending_map_t::iterator itPending = mGetPending.find(pending_material_t(region_id, material_id));
+ if (mGetPending.end() == itPending)
+ {
+ mGetPending.insert(std::pair<pending_material_t, F64>(pending_material_t(region_id, material_id), LLFrameTimer::getTotalSeconds()));
+ }
+ else
+ {
+ itPending->second = LLFrameTimer::getTotalSeconds();
+ }
+}
+
+const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id)
+{
+ LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
+ LLMaterialPtr material;
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (mMaterials.end() != itMaterial)
+ {
+ material = itMaterial->second;
+ LL_DEBUGS("Materials") << " found material " << LL_ENDL;
+ }
+ else
+ {
+ if (!isGetPending(region_id, material_id))
+ {
+ LL_DEBUGS("Materials") << " material pending " << material_id << LL_ENDL;
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ if (mGetQueue.end() == itQueue)
+ {
+ LL_DEBUGS("Materials") << "mGetQueue add region " << region_id << " pending " << material_id << LL_ENDL;
+ std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
+ itQueue = ret.first;
+ }
+ itQueue->second.insert(material_id);
+ markGetPending(region_id, material_id);
+ }
+ LL_DEBUGS("Materials") << " returning empty material " << LL_ENDL;
+ material = LLMaterialPtr();
+ }
+ return material;
+}
+
+boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id, LLMaterialMgr::get_callback_t::slot_type cb)
+{
+ boost::signals2::connection connection;
+
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (itMaterial != mMaterials.end())
+ {
+ LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL;
+ get_callback_t signal;
+ signal.connect(cb);
+ signal(material_id, itMaterial->second);
+ connection = boost::signals2::connection();
+ }
+ else
+ {
+ if (!isGetPending(region_id, material_id))
+ {
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ if (mGetQueue.end() == itQueue)
+ {
+ LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL;
+ std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
+ itQueue = ret.first;
+ }
+ LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL;
+ itQueue->second.insert(material_id);
+ markGetPending(region_id, material_id);
+ }
+
+ get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
+ if (itCallback == mGetCallbacks.end())
+ {
+ std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, new get_callback_t()));
+ itCallback = ret.first;
+ }
+ connection = itCallback->second->connect(cb);;
+ }
+
+ return connection;
+}
+
+boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, LLMaterialMgr::get_callback_te_t::slot_type cb)
+{
+ boost::signals2::connection connection;
+
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (itMaterial != mMaterials.end())
+ {
+ LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL;
+ get_callback_te_t signal;
+ signal.connect(cb);
+ signal(material_id, itMaterial->second, te);
+ connection = boost::signals2::connection();
+ }
+ else
+ {
+ if (!isGetPending(region_id, material_id))
+ {
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ if (mGetQueue.end() == itQueue)
+ {
+ LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL;
+ std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
+ itQueue = ret.first;
+ }
+ LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL;
+ itQueue->second.insert(material_id);
+ markGetPending(region_id, material_id);
+ }
+
+ TEMaterialPair te_mat_pair;
+ te_mat_pair.te = te;
+ te_mat_pair.materialID = material_id;
+
+ get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair);
+ if (itCallback == mGetTECallbacks.end())
+ {
+ std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t()));
+ itCallback = ret.first;
+ }
+ connection = itCallback->second->connect(cb);
+ }
+
+ return connection;
+}
+
+bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id) const
+{
+ getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id);
+ return (mGetAllPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_GET_TIMEOUT);
+}
+
+void LLMaterialMgr::getAll(const LLUUID& region_id)
+{
+ if (!isGetAllPending(region_id))
+ {
+ LL_DEBUGS("Materials") << "queuing for region " << region_id << LL_ENDL;
+ mGetAllQueue.insert(region_id);
+ }
+ else
+ {
+ LL_DEBUGS("Materials") << "already pending for region " << region_id << LL_ENDL;
+ }
+}
+
+boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMaterialMgr::getall_callback_t::slot_type cb)
+{
+ if (!isGetAllPending(region_id))
+ {
+ mGetAllQueue.insert(region_id);
+ }
+
+ getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
+ if (mGetAllCallbacks.end() == itCallback)
+ {
+ std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_id, new getall_callback_t()));
+ itCallback = ret.first;
+ }
+ return itCallback->second->connect(cb);;
+}
+
+void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material)
+{
+ put_queue_t::iterator itQueue = mPutQueue.find(object_id);
+ if (mPutQueue.end() == itQueue)
+ {
+ LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL;
+ mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t()));
+ itQueue = mPutQueue.find(object_id);
+ }
+
+ facematerial_map_t::iterator itFace = itQueue->second.find(te);
+ if (itQueue->second.end() == itFace)
+ {
+ itQueue->second.insert(std::pair<U8, LLMaterial>(te, material));
+ }
+ else
+ {
+ itFace->second = material;
+ }
+}
+
+void LLMaterialMgr::remove(const LLUUID& object_id, const U8 te)
+{
+ put(object_id, te, LLMaterial::null);
+}
+
+const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data)
+{
+ LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (mMaterials.end() == itMaterial)
+ {
+ LL_DEBUGS("Materials") << "new material" << LL_ENDL;
+ LLMaterialPtr newMaterial(new LLMaterial(material_data));
+ std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial));
+ itMaterial = ret.first;
+ }
+
+ TEMaterialPair te_mat_pair;
+ te_mat_pair.materialID = material_id;
+
+ U32 i = 0;
+ while (i < LLTEContents::MAX_TES)
+ {
+ te_mat_pair.te = i++;
+ get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
+ if (itCallbackTE != mGetTECallbacks.end())
+ {
+ (*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
+ delete itCallbackTE->second;
+ mGetTECallbacks.erase(itCallbackTE);
+ }
+ }
+
+ get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
+ if (itCallback != mGetCallbacks.end())
+ {
+ (*itCallback->second)(material_id, itMaterial->second);
+
+ delete itCallback->second;
+ mGetCallbacks.erase(itCallback);
+ }
+
+ mGetPending.erase(pending_material_t(region_id, material_id));
+
+ return itMaterial->second;
+}
+
+void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUID& region_id)
+{
+ if (!success)
+ {
+ // *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
+ return;
+ }
+
+ llassert(content.isMap());
+ llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
+
+ LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
+ std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
+ std::istringstream content_stream(content_string);
+
+ LLSD response_data;
+ if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+ {
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ return;
+ }
+
+ llassert(response_data.isArray());
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
+ for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial)
+ {
+ const LLSD& material_data = *itMaterial;
+ llassert(material_data.isMap());
+
+ llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary());
+ LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary());
+
+ llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD));
+ llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap());
+
+ setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]);
+ }
+}
+
+void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id)
+{
+ if (!success)
+ {
+ // *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
+ return;
+ }
+
+ llassert(content.isMap());
+ llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
+
+ LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
+ std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
+ std::istringstream content_stream(content_string);
+
+ LLSD response_data;
+ if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+ {
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ return;
+ }
+
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ material_map_t materials;
+
+ llassert(response_data.isArray());
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
+ for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial)
+ {
+ const LLSD& material_data = *itMaterial;
+ llassert(material_data.isMap());
+
+ llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary());
+ LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary());
+ if (mGetQueue.end() != itQueue)
+ {
+ itQueue->second.erase(material_id);
+ }
+
+ llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD));
+ llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap());
+ LLMaterialPtr material = setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]);
+
+ materials[material_id] = material;
+ }
+
+ getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
+ if (itCallback != mGetAllCallbacks.end())
+ {
+ (*itCallback->second)(region_id, materials);
+
+ delete itCallback->second;
+ mGetAllCallbacks.erase(itCallback);
+ }
+
+ if ( (mGetQueue.end() != itQueue) && (itQueue->second.empty()) )
+ {
+ mGetQueue.erase(itQueue);
+ }
+
+ LL_DEBUGS("Materials")<< "recording that getAll has been done for region id " << region_id << LL_ENDL;
+ mGetAllRequested.insert(region_id); // prevents subsequent getAll requests for this region
+ mGetAllPending.erase(region_id); // Invalidates region_id
+}
+
+void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
+{
+ if (!success)
+ {
+ // *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
+ return;
+ }
+
+ llassert(content.isMap());
+ llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
+
+ LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
+ std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
+ std::istringstream content_stream(content_string);
+
+ LLSD response_data;
+ if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+ {
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ return;
+ }
+ else
+ {
+ llassert(response_data.isArray());
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
+ for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter)
+ {
+# ifndef LL_RELEASE_FOR_DOWNLOAD
+ const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning
+# endif
+ llassert(face_data.isMap());
+
+ llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(face_data[MATERIALS_CAP_OBJECT_ID_FIELD].isInteger());
+ // U32 local_id = face_data[MATERIALS_CAP_OBJECT_ID_FIELD].asInteger();
+
+ llassert(face_data.has(MATERIALS_CAP_FACE_FIELD));
+ llassert(face_data[MATERIALS_CAP_FACE_FIELD].isInteger());
+ // S32 te = face_data[MATERIALS_CAP_FACE_FIELD].asInteger();
+
+ llassert(face_data.has(MATERIALS_CAP_MATERIAL_ID_FIELD));
+ llassert(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].isBinary());
+ // LLMaterialID material_id(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].asBinary());
+
+ // *TODO: do we really still need to process this?
+ }
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_MATERIALS_IDLE("Materials");
+
+void LLMaterialMgr::onIdle(void*)
+{
+ LLFastTimer t(FTM_MATERIALS_IDLE);
+
+ LLMaterialMgr* instancep = LLMaterialMgr::getInstance();
+
+ if (!instancep->mGetQueue.empty())
+ {
+ instancep->processGetQueue();
+ }
+
+ if (!instancep->mGetAllQueue.empty())
+ {
+ instancep->processGetAllQueue();
+ }
+
+ static LLFrameTimer mPutTimer;
+ if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) )
+ {
+ instancep->processPutQueue();
+ mPutTimer.resetWithExpiry(MATERIALS_PUT_THROTTLE_SECS);
+ }
+}
+
+void LLMaterialMgr::processGetQueue()
+{
+ get_queue_t::iterator loopRegionQueue = mGetQueue.begin();
+ while (mGetQueue.end() != loopRegionQueue)
+ {
+ get_queue_t::iterator itRegionQueue = loopRegionQueue++;
+
+ const LLUUID& region_id = itRegionQueue->first;
+ if (isGetAllPending(region_id))
+ {
+ continue;
+ }
+
+ const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
+ if (!regionp)
+ {
+ LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
+ mGetQueue.erase(itRegionQueue);
+ continue;
+ }
+ else if (!regionp->capabilitiesReceived())
+ {
+ continue;
+ }
+ else if (mGetAllRequested.end() == mGetAllRequested.find(region_id))
+ {
+ LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL;
+ getAll(region_id);
+ continue;
+ }
+
+ const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+ if (capURL.empty())
+ {
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
+ mGetQueue.erase(itRegionQueue);
+ continue;
+ }
+
+ LLSD materialsData = LLSD::emptyArray();
+
+ material_queue_t& materials = itRegionQueue->second;
+ material_queue_t::iterator loopMaterial = materials.begin();
+ while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) )
+ {
+ material_queue_t::iterator itMaterial = loopMaterial++;
+ materialsData.append((*itMaterial).asLLSD());
+ materials.erase(itMaterial);
+ markGetPending(region_id, *itMaterial);
+ }
+ if (materials.empty())
+ {
+ mGetQueue.erase(itRegionQueue);
+ }
+
+ std::string materialString = zip_llsd(materialsData);
+
+ S32 materialSize = materialString.size();
+ if (materialSize <= 0)
+ {
+ LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL;
+ return;
+ }
+
+ LLSD::Binary materialBinary;
+ materialBinary.resize(materialSize);
+ memcpy(materialBinary.data(), materialString.data(), materialSize);
+
+ LLSD postData = LLSD::emptyMap();
+ postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
+
+ LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id));
+ LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."
+ << "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
+ LLHTTPClient::post(capURL, postData, materialsResponder);
+ }
+}
+
+void LLMaterialMgr::processGetAllQueue()
+{
+ getall_queue_t::iterator loopRegion = mGetAllQueue.begin();
+ while (mGetAllQueue.end() != loopRegion)
+ {
+ getall_queue_t::iterator itRegion = loopRegion++;
+
+ const LLUUID& region_id = *itRegion;
+ LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
+ if (regionp == NULL)
+ {
+ LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
+ clearGetQueues(region_id); // Invalidates region_id
+ continue;
+ }
+ else if (!regionp->capabilitiesReceived())
+ {
+ continue;
+ }
+
+ std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+ if (capURL.empty())
+ {
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL;
+ clearGetQueues(region_id); // Invalidates region_id
+ continue;
+ }
+
+ LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL;
+ LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
+ LLHTTPClient::get(capURL, materialsResponder);
+ mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
+ mGetAllQueue.erase(itRegion); // Invalidates region_id
+ }
+}
+
+void LLMaterialMgr::processPutQueue()
+{
+ typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map;
+ regionput_request_map requests;
+
+ put_queue_t::iterator loopQueue = mPutQueue.begin();
+ while (mPutQueue.end() != loopQueue)
+ {
+ put_queue_t::iterator itQueue = loopQueue++;
+
+ const LLUUID& object_id = itQueue->first;
+ const LLViewerObject* objectp = gObjectList.findObject(object_id);
+ if ( (!objectp) || (!objectp->getRegion()) )
+ {
+ LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL;
+
+ mPutQueue.erase(itQueue);
+ continue;
+ }
+
+ const LLViewerRegion* regionp = objectp->getRegion();
+ if (!regionp->capabilitiesReceived())
+ {
+ continue;
+ }
+
+ LLSD& facesData = requests[regionp];
+
+ facematerial_map_t& face_map = itQueue->second;
+ facematerial_map_t::iterator itFace = face_map.begin();
+ while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) )
+ {
+ LLSD faceData = LLSD::emptyMap();
+ faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
+ faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
+ if (!itFace->second.isNull())
+ {
+ faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
+ }
+ facesData.append(faceData);
+ face_map.erase(itFace++);
+ }
+ if (face_map.empty())
+ {
+ mPutQueue.erase(itQueue);
+ }
+ }
+
+ for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
+ {
+ std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME);
+ if (capURL.empty())
+ {
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL;
+ continue;
+ }
+
+ LLSD materialsData = LLSD::emptyMap();
+ materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second;
+
+ std::string materialString = zip_llsd(materialsData);
+
+ S32 materialSize = materialString.size();
+
+ if (materialSize > 0)
+ {
+ LLSD::Binary materialBinary;
+ materialBinary.resize(materialSize);
+ memcpy(materialBinary.data(), materialString.data(), materialSize);
+
+ LLSD putData = LLSD::emptyMap();
+ putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
+
+ LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
+ LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
+ LLHTTPClient::put(capURL, putData, materialsResponder);
+ }
+ else
+ {
+ LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
+ }
+ }
+}
+
+void LLMaterialMgr::clearGetQueues(const LLUUID& region_id)
+{
+ mGetQueue.erase(region_id);
+ for (get_pending_map_t::iterator itPending = mGetPending.begin(); itPending != mGetPending.end();)
+ {
+ if (region_id == itPending->first.first)
+ {
+ mGetPending.erase(itPending++);
+ }
+ else
+ {
+ ++itPending;
+ }
+ }
+
+ mGetAllQueue.erase(region_id);
+ mGetAllRequested.erase(region_id);
+ mGetAllPending.erase(region_id);
+ mGetAllCallbacks.erase(region_id);
+}
+
+void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp)
+{
+ clearGetQueues(regionp->getRegionID());
+ // Put doesn't need clearing: objects that can't be found will clean up in processPutQueue()
+}
+
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
new file mode 100644
index 0000000000..e317a791ad
--- /dev/null
+++ b/indra/newview/llmaterialmgr.h
@@ -0,0 +1,130 @@
+/**
+ * @file llmaterialmgr.h
+ * @brief Material manager
+ *
+ * $LicenseInfo:firstyear=2006&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_LLMATERIALMGR_H
+#define LL_LLMATERIALMGR_H
+
+#include "llmaterial.h"
+#include "llmaterialid.h"
+#include "llsingleton.h"
+
+class LLViewerRegion;
+
+class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
+{
+ friend class LLSingleton<LLMaterialMgr>;
+protected:
+ LLMaterialMgr();
+ virtual ~LLMaterialMgr();
+
+public:
+ typedef std::map<LLMaterialID, LLMaterialPtr> material_map_t;
+
+ typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr)> get_callback_t;
+ const LLMaterialPtr get(const LLUUID& region_id, const LLMaterialID& material_id);
+ boost::signals2::connection get(const LLUUID& region_id, const LLMaterialID& material_id, get_callback_t::slot_type cb);
+
+ typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr, U32 te)> get_callback_te_t;
+ boost::signals2::connection getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, get_callback_te_t::slot_type cb);
+
+ typedef boost::signals2::signal<void (const LLUUID&, const material_map_t&)> getall_callback_t;
+ void getAll(const LLUUID& region_id);
+ boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb);
+ void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
+ void remove(const LLUUID& object_id, const U8 te);
+
+protected:
+ void clearGetQueues(const LLUUID& region_id);
+ bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const;
+ bool isGetAllPending(const LLUUID& region_id) const;
+ void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id);
+ const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data);
+
+ static void onIdle(void*);
+ void processGetQueue();
+ void onGetResponse(bool success, const LLSD& content, const LLUUID& region_id);
+ void processGetAllQueue();
+ void onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id);
+ void processPutQueue();
+ void onPutResponse(bool success, const LLSD& content);
+ void onRegionRemoved(LLViewerRegion* regionp);
+
+protected:
+ typedef std::set<LLMaterialID> material_queue_t;
+ typedef std::map<LLUUID, material_queue_t> get_queue_t;
+ get_queue_t mGetQueue;
+ typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
+ typedef std::map<const pending_material_t, F64> get_pending_map_t;
+ get_pending_map_t mGetPending;
+ typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
+ get_callback_map_t mGetCallbacks;
+
+ // struct for TE-specific material ID query
+ class TEMaterialPair
+ {
+ public:
+
+ U32 te;
+ LLMaterialID materialID;
+
+ bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); }
+ };
+
+ friend inline bool operator<(
+ const LLMaterialMgr::TEMaterialPair& lhs,
+ const LLMaterialMgr::TEMaterialPair& rhs)
+ {
+ return (lhs.te < rhs.te) ? TRUE :
+ (lhs.materialID < rhs.materialID);
+ }
+
+ struct TEMaterialPairHasher
+ {
+ enum { bucket_size = 8 };
+ size_t operator()(const TEMaterialPair& key_value) const { return *((size_t*)key_value.materialID.get()); } // cheesy, but effective
+ bool operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; }
+ };
+
+ typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t;
+ get_callback_te_map_t mGetTECallbacks;
+
+ typedef std::set<LLUUID> getall_queue_t;
+ getall_queue_t mGetAllQueue;
+ getall_queue_t mGetAllRequested;
+ typedef std::map<LLUUID, F64> getall_pending_map_t;
+ getall_pending_map_t mGetAllPending;
+ typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t;
+ getall_callback_map_t mGetAllCallbacks;
+
+ typedef std::map<U8, LLMaterial> facematerial_map_t;
+ typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
+ put_queue_t mPutQueue;
+
+ material_map_t mMaterials;
+};
+
+#endif // LL_LLMATERIALMGR_H
+
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 95289f7167..a888445060 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1,3 +1,4 @@
+
/**
* @file llmeshrepository.cpp
* @brief Mesh repository implementation.
diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h
index 6533d55f2f..81acc31863 100755
--- a/indra/newview/llpaneleditwearable.h
+++ b/indra/newview/llpaneleditwearable.h
@@ -95,7 +95,7 @@ private:
void toggleTypeSpecificControls(LLWearableType::EType type);
void updateTypeSpecificControls(LLWearableType::EType type);
- // alpha mask checkboxes
+ //alpha mask checkboxes
void configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name);
void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te);
void updateAlphaCheckboxes();
@@ -155,7 +155,7 @@ private:
LLPanel *mPanelEyes;
LLPanel *mPanelHair;
- // clothes
+ //clothes
LLPanel *mPanelShirt;
LLPanel *mPanelPants;
LLPanel *mPanelShoes;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 445c0d811f..911af9df04 100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -46,6 +46,7 @@
#include "lldrawpoolbump.h"
#include "llface.h"
#include "lllineeditor.h"
+#include "llmaterialmgr.h"
#include "llmediaentry.h"
#include "llnotificationsutil.h"
#include "llresmgr.h"
@@ -55,10 +56,12 @@
#include "lltexturectrl.h"
#include "lltextureentry.h"
#include "lltooldraganddrop.h"
+#include "lltrans.h"
#include "llui.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
#include "llviewerobject.h"
+#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llvovolume.h"
#include "lluictrlfactory.h"
@@ -66,6 +69,48 @@
#include "llviewertexturelist.h"
//
+// 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 MATTYPE_DIFFUSE = 0; // Diffuse material texture
+const S32 MATTYPE_NORMAL = 1; // Normal map
+const S32 MATTYPE_SPECULAR = 2; // Specular map
+const S32 ALPHAMODE_NONE = 0; // No alpha mask applied
+const S32 ALPHAMODE_BLEND = 1; // Alpha blending mode
+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
+
+//
+// "Use texture" label for normal/specular type comboboxes
+// Filled in at initialization from translated strings
+//
+std::string USE_TEXTURE;
+
+// Things the UI provides...
+//
+LLUUID LLPanelFace::getCurrentNormalMap() { return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); }
+LLUUID LLPanelFace::getCurrentSpecularMap() { return getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); }
+U32 LLPanelFace::getCurrentShininess() { return getChild<LLComboBox>("combobox shininess")->getCurrentIndex(); }
+U32 LLPanelFace::getCurrentBumpiness() { return getChild<LLComboBox>("combobox bumpiness")->getCurrentIndex(); }
+U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)getChild<LLComboBox>("combobox alphamode")->getCurrentIndex(); }
+U8 LLPanelFace::getCurrentAlphaMaskCutoff() { return (U8)getChild<LLUICtrl>("maskcutoff")->getValue().asInteger(); }
+U8 LLPanelFace::getCurrentEnvIntensity() { return (U8)getChild<LLUICtrl>("environment")->getValue().asInteger(); }
+U8 LLPanelFace::getCurrentGlossiness() { return (U8)getChild<LLUICtrl>("glossiness")->getValue().asInteger(); }
+F32 LLPanelFace::getCurrentBumpyRot() { return getChild<LLUICtrl>("bumpyRot")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyScaleU() { return getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyScaleV() { return getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyOffsetU() { return getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyOffsetV() { return getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyRot() { return getChild<LLUICtrl>("shinyRot")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyScaleU() { return getChild<LLUICtrl>("shinyScaleU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyScaleV() { return getChild<LLUICtrl>("shinyScaleV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal(); }
+
+//
// Methods
//
@@ -73,21 +118,40 @@ BOOL LLPanelFace::postBuild()
{
childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
+ childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this);
childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
- childSetAction("button apply",&LLPanelFace::onClickApply,this);
+ childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);
childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
+
+ childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this);
+ childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this);
+ childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this);
+ childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this);
+ childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this);
+ childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this);
+ childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this);
+ childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this);
+ childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this);
+ childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this);
+ childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
+ childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
+ childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
+
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
LLTextureCtrl* mTextureCtrl;
+ LLTextureCtrl* mShinyTextureCtrl;
+ LLTextureCtrl* mBumpyTextureCtrl;
LLColorSwatchCtrl* mColorSwatch;
+ LLColorSwatchCtrl* mShinyColorSwatch;
LLComboBox* mComboTexGen;
+ LLComboBox* mComboMatMedia;
+ LLComboBox* mComboMatType;
LLCheckBoxCtrl *mCheckFullbright;
@@ -97,6 +161,7 @@ BOOL LLPanelFace::postBuild()
LLSpinCtrl* mCtrlGlow;
setMouseOpaque(FALSE);
+
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
if(mTextureCtrl)
{
@@ -106,12 +171,49 @@ BOOL LLPanelFace::postBuild()
mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
mTextureCtrl->setFollowsTop();
mTextureCtrl->setFollowsLeft();
mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
}
+ mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control");
+ if(mShinyTextureCtrl)
+ {
+ mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" )));
+ mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
+ mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mShinyTextureCtrl->setFollowsTop();
+ mShinyTextureCtrl->setFollowsLeft();
+ mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+
+ mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control");
+ if(mBumpyTextureCtrl)
+ {
+ mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" )));
+ mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" )));
+ mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
+ mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mBumpyTextureCtrl->setFollowsTop();
+ mBumpyTextureCtrl->setFollowsLeft();
+ mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+
mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
if(mColorSwatch)
{
@@ -123,6 +225,15 @@ BOOL LLPanelFace::postBuild()
mColorSwatch->setCanApplyImmediately(TRUE);
}
+ mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
+ if(mShinyColorSwatch)
+ {
+ mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2));
+ mShinyColorSwatch->setFollowsTop();
+ mShinyColorSwatch->setFollowsLeft();
+ mShinyColorSwatch->setCanApplyImmediately(TRUE);
+ }
+
mLabelColorTransp = getChild<LLTextBox>("color trans");
if(mLabelColorTransp)
{
@@ -152,6 +263,20 @@ BOOL LLPanelFace::postBuild()
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
}
+ mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
+ if(mComboMatMedia)
+ {
+ mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ }
+
+ mComboMatType = getChild<LLComboBox>("combobox mattype");
+ if(mComboMatType)
+ {
+ mComboMatType->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
+ mComboMatType->selectNthItem(MATTYPE_DIFFUSE);
+ }
+
mCtrlGlow = getChild<LLSpinCtrl>("glow");
if(mCtrlGlow)
{
@@ -165,8 +290,10 @@ BOOL LLPanelFace::postBuild()
}
LLPanelFace::LLPanelFace()
-: LLPanel()
+: LLPanel(),
+ mIsAlpha(false)
{
+ USE_TEXTURE = LLTrans::getString("use_texture");
}
@@ -193,12 +320,32 @@ void LLPanelFace::sendTexture()
}
}
-void LLPanelFace::sendBump()
+void LLPanelFace::sendBump(U32 bumpiness)
{
- LLComboBox* mComboBumpiness = getChild<LLComboBox>("combobox bumpiness");
- if(!mComboBumpiness)return;
- U8 bump = (U8) mComboBumpiness->getCurrentIndex() & TEM_BUMP_MASK;
- LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
+ LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ if (bumpiness < BUMPY_TEXTURE)
+ {
+ LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL;
+ bumpytexture_ctrl->clear();
+ bumpytexture_ctrl->setImageAssetID(LLUUID());
+ }
+
+ updateBumpyControls(bumpiness == BUMPY_TEXTURE, true);
+
+ LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID();
+
+ U8 bump = (U8) bumpiness & TEM_BUMP_MASK;
+
+ // Clear legacy bump to None when using an actual normal map
+ //
+ if (!current_normal_map.isNull())
+ bump = 0;
+
+ // Set the normal map or reset it to null as appropriate
+ //
+ LLSelectedTEMaterial::setNormalID(this, current_normal_map);
+
+ LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
}
void LLPanelFace::sendTexGen()
@@ -209,12 +356,28 @@ void LLPanelFace::sendTexGen()
LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );
}
-void LLPanelFace::sendShiny()
+void LLPanelFace::sendShiny(U32 shininess)
{
- LLComboBox* mComboShininess = getChild<LLComboBox>("combobox shininess");
- if(!mComboShininess)return;
- U8 shiny = (U8) mComboShininess->getCurrentIndex() & TEM_SHINY_MASK;
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+
+ if (shininess < SHINY_TEXTURE)
+ {
+ texture_ctrl->clear();
+ texture_ctrl->setImageAssetID(LLUUID());
+ }
+
+ LLUUID specmap = getCurrentSpecularMap();
+
+ U8 shiny = (U8) shininess & TEM_SHINY_MASK;
+ if (!specmap.isNull())
+ shiny = 0;
+
+ LLSelectedTEMaterial::setSpecularID(this, specmap);
+
LLSelectMgr::getInstance()->selectionSetShiny( shiny );
+
+ updateShinyControls(!specmap.isNull(), true);
+
}
void LLPanelFace::sendFullbright()
@@ -268,22 +431,16 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
LLSpinCtrl* ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");
LLSpinCtrl* ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");
LLSpinCtrl* ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot");
- LLCheckBoxCtrl* checkFlipScaleS = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip s");
- LLCheckBoxCtrl* checkFlipScaleT = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip t");
LLComboBox* comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
llassert(comboTexGen);
llassert(object);
if (ctrlTexScaleS)
{
- valid = !ctrlTexScaleS->getTentative() || !checkFlipScaleS->getTentative();
+ valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();
if (valid)
{
value = ctrlTexScaleS->get();
- if( checkFlipScaleS->get() )
- {
- value = -value;
- }
if (comboTexGen &&
comboTexGen->getCurrentIndex() == 1)
{
@@ -295,14 +452,14 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
if (ctrlTexScaleT)
{
- valid = !ctrlTexScaleT->getTentative() || !checkFlipScaleT->getTentative();
+ valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();
if (valid)
{
value = ctrlTexScaleT->get();
- if( checkFlipScaleT->get() )
- {
- value = -value;
- }
+ //if( checkFlipScaleT->get() )
+ //{
+ // value = -value;
+ //}
if (comboTexGen &&
comboTexGen->getCurrentIndex() == 1)
{
@@ -458,16 +615,9 @@ void LLPanelFace::sendTextureInfo()
{
if ((bool)childGetValue("checkbox planar align").asBoolean())
{
- struct f1 : public LLSelectedTEGetFunctor<LLFace *>
- {
- LLFace* get(LLViewerObject* object, S32 te)
- {
- return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
- }
- } get_last_face_func;
- LLFace* last_face;
- LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_face);
-
+ LLFace* last_face = NULL;
+ bool identical_face =false;
+ LLSelectedTE::getFace(last_face, identical_face);
LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
}
@@ -483,6 +633,11 @@ void LLPanelFace::sendTextureInfo()
void LLPanelFace::getState()
{
+ updateUI();
+}
+
+void LLPanelFace::updateUI()
+{ //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible)
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
if( objectp
@@ -492,409 +647,727 @@ void LLPanelFace::getState()
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- getChildView("textbox autofix")->setEnabled(editable);
getChildView("button align")->setEnabled(editable);
+
+ LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
+ if (combobox_matmedia)
+ {
+ if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
+ {
+ combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
+ }
+ }
+ else
+ {
+ llwarns << "failed getChild for 'combobox matmedia'" << llendl;
+ }
+ getChildView("combobox matmedia")->setEnabled(editable);
+
+ LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype");
+ if (combobox_mattype)
+ {
+ if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE)
+ {
+ combobox_mattype->selectNthItem(MATTYPE_DIFFUSE);
+ }
+ }
+ else
+ {
+ LL_WARNS("Materials") << "failed getChild for 'combobox mattype'" << LL_ENDL;
+ }
+ getChildView("combobox mattype")->setEnabled(editable);
+
+ updateVisibility();
+
+ bool identical = true; // true because it is anded below
+ bool identical_diffuse = false;
+ bool identical_norm = false;
+ bool identical_spec = false;
+
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+ LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
- //if ( LLMediaEngine::getInstance()->getMediaRenderer () )
- // if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
- // {
- //
- // //mLabelTexAutoFix->setEnabled ( editable );
- //
- // //mBtnAutoFix->setEnabled ( editable );
- // }
- getChildView("button apply")->setEnabled(editable);
-
- bool identical;
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+ LLUUID id;
+ LLUUID normmap_id;
+ LLUUID specmap_id;
+
+ // Color swatch
+ {
+ getChildView("color label")->setEnabled(editable);
+ }
+ LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+
+ LLColor4 color = LLColor4::white;
+ bool identical_color = false;
+
+ if(mColorSwatch)
+ {
+ LLSelectedTE::getColor(color, identical_color);
+
+ mColorSwatch->setOriginal(color);
+ mColorSwatch->set(color, TRUE);
+
+ mColorSwatch->setValid(editable);
+ mColorSwatch->setEnabled( editable );
+ mColorSwatch->setCanApplyImmediately( editable );
+ }
+
+ // Color transparency
+ getChildView("color trans")->setEnabled(editable);
+
+ F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
+ getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
+ getChildView("ColorTrans")->setEnabled(editable);
+
+ // Specular map
+ LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec);
- // Texture
+ U8 shiny = 0;
+ bool identical_shiny = false;
+
+ // Shiny
+ LLSelectedTE::getShiny(shiny, identical_shiny);
+ identical = identical && identical_shiny;
+
+ shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE;
+
+ LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess");
+ if (combobox_shininess)
{
- LLUUID id;
- struct f1 : public LLSelectedTEGetFunctor<LLUUID>
+ combobox_shininess->selectNthItem((S32)shiny);
+ }
+
+ getChildView("label shininess")->setEnabled(editable);
+ getChildView("combobox shininess")->setEnabled(editable);
+
+ getChildView("label glossiness")->setEnabled(editable);
+ getChildView("glossiness")->setEnabled(editable);
+
+ getChildView("label environment")->setEnabled(editable);
+ getChildView("environment")->setEnabled(editable);
+ getChildView("label shinycolor")->setEnabled(editable);
+
+ getChild<LLUICtrl>("combobox shininess")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("glossiness")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("environment")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec);
+
+ LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
+ if(mShinyColorSwatch)
+ {
+ mShinyColorSwatch->setValid(editable);
+ mShinyColorSwatch->setEnabled( editable );
+ mShinyColorSwatch->setCanApplyImmediately( editable );
+ }
+
+ U8 bumpy = 0;
+ // Bumpy
+ {
+ bool identical_bumpy = false;
+ LLSelectedTE::getBumpmap(bumpy,identical_bumpy);
+
+ LLUUID norm_map_id = getCurrentNormalMap();
+ LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness");
+
+ bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
+
+ if (combobox_bumpiness)
{
- LLUUID get(LLViewerObject* object, S32 te_index)
- {
- LLUUID id;
-
- LLViewerTexture* image = object->getTEImage(te_index);
- if (image) id = image->getID();
-
- if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
- {
- LLTextureEntry *te = object->getTE(te_index);
- if (te)
- {
- LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ;
- if(!tex)
- {
- tex = LLViewerFetchedTexture::sDefaultImagep;
- }
- if (tex)
- {
- id = tex->getID();
- }
- }
- }
- return id;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
+ combobox_bumpiness->selectNthItem((S32)bumpy);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
+ }
+
+ getChildView("combobox bumpiness")->setEnabled(editable);
+ getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy);
+ getChildView("label bumpiness")->setEnabled(editable);
+ }
+
+ // Texture
+ {
+ LLSelectedTE::getTexId(id,identical_diffuse);
+
+ // Normal map
+ LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm);
+
+ mIsAlpha = FALSE;
+ LLGLenum image_format = GL_RGB;
+ bool identical_image_format = false;
+ LLSelectedTE::getImageFormat(image_format, identical_image_format);
+
+ mIsAlpha = FALSE;
+ switch (image_format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ mIsAlpha = TRUE;
+ }
+ break;
+
+ case GL_RGB: break;
+ default:
+ {
+ llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl;
+ }
+ break;
+ }
if(LLViewerMedia::textureHasMedia(id))
{
- getChildView("textbox autofix")->setEnabled(editable);
getChildView("button align")->setEnabled(editable);
}
- if (identical)
+ // Diffuse Alpha Mode
+
+ // Init to the default that is appropriate for the alpha content of the asset
+ //
+ U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ bool identical_alpha_mode = false;
+
+ // See if that's been overridden by a material setting for same...
+ //
+ LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha);
+
+ LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode");
+ if (combobox_alphamode)
+ {
+ //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
+ // Want masking? Want emissive? Tough! You get BLEND!
+ alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode;
+
+ // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none
+ alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
+ }
+
+ updateAlphaControls();
+
+ if(texture_ctrl)
{
- // All selected have the same texture
- if(texture_ctrl)
+ if (identical_diffuse)
+ {
+ 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);
+ }
+ else if (id.isNull())
{
+ // None selected
texture_ctrl->setTentative( FALSE );
+ texture_ctrl->setEnabled( FALSE );
+ texture_ctrl->setImageAssetID( LLUUID::null );
+ getChildView("combobox alphamode")->setEnabled( FALSE );
+ getChildView("label alphamode")->setEnabled( FALSE );
+ getChildView("maskcutoff")->setEnabled( FALSE);
+ getChildView("label maskcutoff")->setEnabled( FALSE );
+ }
+ else
+ {
+ // Tentative: multiple selected with different textures
+ 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);
}
}
- else
- {
- if(texture_ctrl)
+
+ if (shinytexture_ctrl)
+ {
+ if (identical_spec && (shiny == SHINY_TEXTURE))
{
- if( id.isNull() )
- {
- // None selected
- texture_ctrl->setTentative( FALSE );
- texture_ctrl->setEnabled( FALSE );
- texture_ctrl->setImageAssetID( LLUUID::null );
- }
- else
- {
- // Tentative: multiple selected with different textures
- texture_ctrl->setTentative( TRUE );
- texture_ctrl->setEnabled( editable );
- texture_ctrl->setImageAssetID( id );
- }
+ shinytexture_ctrl->setTentative( FALSE );
+ shinytexture_ctrl->setEnabled( editable );
+ shinytexture_ctrl->setImageAssetID( specmap_id );
+ }
+ else if (specmap_id.isNull())
+ {
+ shinytexture_ctrl->setTentative( FALSE );
+ shinytexture_ctrl->setEnabled( editable );
+ shinytexture_ctrl->setImageAssetID( LLUUID::null );
+ }
+ else
+ {
+ shinytexture_ctrl->setTentative( TRUE );
+ shinytexture_ctrl->setEnabled( editable );
+ shinytexture_ctrl->setImageAssetID( specmap_id );
+ }
+ }
+
+ if (bumpytexture_ctrl)
+ {
+ if (identical_norm && (bumpy == BUMPY_TEXTURE))
+ {
+ bumpytexture_ctrl->setTentative( FALSE );
+ bumpytexture_ctrl->setEnabled( editable );
+ bumpytexture_ctrl->setImageAssetID( normmap_id );
+ }
+ else if (normmap_id.isNull())
+ {
+ bumpytexture_ctrl->setTentative( FALSE );
+ bumpytexture_ctrl->setEnabled( editable );
+ bumpytexture_ctrl->setImageAssetID( LLUUID::null );
+ }
+ else
+ {
+ bumpytexture_ctrl->setTentative( TRUE );
+ bumpytexture_ctrl->setEnabled( editable );
+ bumpytexture_ctrl->setImageAssetID( normmap_id );
}
}
}
-
// planar align
bool align_planar = false;
bool identical_planar_aligned = false;
- bool is_planar = false;
{
LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
align_planar = (cb_planar_align && cb_planar_align->get());
- struct f1 : public LLSelectedTEGetFunctor<bool>
- {
- bool get(LLViewerObject* object, S32 face)
- {
- return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR);
- }
- } func;
-
- bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar );
- bool enabled = (editable && texgens_identical && is_planar);
+
+ bool enabled = (editable && isIdenticalPlanarTexgen());
childSetValue("checkbox planar align", align_planar && enabled);
childSetEnabled("checkbox planar align", enabled);
if (align_planar && enabled)
{
- struct f2 : public LLSelectedTEGetFunctor<LLFace *>
- {
- LLFace* get(LLViewerObject* object, S32 te)
- {
- return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
- }
- } get_te_face_func;
- LLFace* last_face;
- LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_face);
+ LLFace* last_face = NULL;
+ bool identical_face = false;
+ LLSelectedTE::getFace(last_face, identical_face);
+
LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face);
// this will determine if the texture param controls are tentative:
identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func);
}
}
+ // Needs to be public and before tex scale settings below to properly reflect
+ // behavior when in planar vs default texgen modes in the
+ // NORSPEC-84 et al
+ //
+ LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
+ bool identical_texgen = true;
+ bool identical_planar_texgen = false;
+
+ {
+ LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
+ identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
+ }
+
// Texture scale
{
- F32 scale_s = 1.f;
- struct f2 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mScaleS;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s );
+ bool identical_diff_scale_s = false;
+ bool identical_spec_scale_s = false;
+ bool identical_norm_scale_s = false;
+
identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexScaleU")->setValue(editable ? llabs(scale_s) : 0);
- getChild<LLUICtrl>("TexScaleU")->setTentative(LLSD((BOOL)(!identical)));
+
+ F32 diff_scale_s = 1.f;
+ F32 spec_scale_s = 1.f;
+ F32 norm_scale_s = 1.f;
+
+ LLSelectedTE::getScaleS( diff_scale_s, identical_diff_scale_s);
+ LLSelectedTEMaterial::getSpecularRepeatX( spec_scale_s, identical_spec_scale_s);
+ LLSelectedTEMaterial::getNormalRepeatX( norm_scale_s, identical_norm_scale_s);
+
+ diff_scale_s = editable ? diff_scale_s : 1.0f;
+ diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ norm_scale_s = editable ? norm_scale_s : 1.0f;
+ norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ spec_scale_s = editable ? spec_scale_s : 1.0f;
+ spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ getChild<LLUICtrl>("TexScaleU")->setValue(diff_scale_s);
+ getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s);
+ getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s);
+
getChildView("TexScaleU")->setEnabled(editable);
- getChild<LLUICtrl>("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE )));
- getChild<LLUICtrl>("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
- getChildView("checkbox flip s")->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);
+ BOOL spec_scale_tentative = !(identical && identical_spec_scale_s);
+
+ getChild<LLUICtrl>("TexScaleU")->setTentative( LLSD(diff_scale_tentative));
+ getChild<LLUICtrl>("shinyScaleU")->setTentative(LLSD(spec_scale_tentative));
+ getChild<LLUICtrl>("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative));
}
{
- F32 scale_t = 1.f;
- struct f3 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mScaleT;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t );
- identical = align_planar ? identical_planar_aligned : identical;
+ bool identical_diff_scale_t = false;
+ bool identical_spec_scale_t = false;
+ bool identical_norm_scale_t = false;
+
+ F32 diff_scale_t = 1.f;
+ F32 spec_scale_t = 1.f;
+ F32 norm_scale_t = 1.f;
+
+ LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t);
+ LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t);
+ LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t);
+
+ diff_scale_t = editable ? diff_scale_t : 1.0f;
+ diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ norm_scale_t = editable ? norm_scale_t : 1.0f;
+ norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ spec_scale_t = editable ? spec_scale_t : 1.0f;
+ spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ BOOL diff_scale_tentative = !identical_diff_scale_t;
+ BOOL norm_scale_tentative = !identical_norm_scale_t;
+ BOOL spec_scale_tentative = !identical_spec_scale_t;
- getChild<LLUICtrl>("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0));
- getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD((BOOL)(!identical)));
getChildView("TexScaleV")->setEnabled(editable);
- getChild<LLUICtrl>("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE )));
- getChild<LLUICtrl>("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
- getChildView("checkbox flip t")->setEnabled(editable);
+ getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull());
+
+ getChild<LLUICtrl>("TexScaleV")->setValue(diff_scale_t);
+ getChild<LLUICtrl>("shinyScaleV")->setValue(norm_scale_t);
+ getChild<LLUICtrl>("bumpyScaleV")->setValue(spec_scale_t);
+
+ getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD(diff_scale_tentative));
+ getChild<LLUICtrl>("shinyScaleV")->setTentative(LLSD(norm_scale_tentative));
+ getChild<LLUICtrl>("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative));
}
// Texture offset
{
- getChildView("tex offset")->setEnabled(editable);
- F32 offset_s = 0.f;
- struct f4 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mOffsetS;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s );
- identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexOffsetU")->setValue(editable ? offset_s : 0);
- getChild<LLUICtrl>("TexOffsetU")->setTentative(!identical);
+ bool identical_diff_offset_s = false;
+ bool identical_norm_offset_s = false;
+ bool identical_spec_offset_s = false;
+
+ F32 diff_offset_s = 0.0f;
+ F32 norm_offset_s = 0.0f;
+ F32 spec_offset_s = 0.0f;
+
+ LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s);
+ LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s);
+ LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s);
+
+ BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s);
+ BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s);
+ BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s);
+
+ getChild<LLUICtrl>("TexOffsetU")->setValue( editable ? diff_offset_s : 0.0f);
+ getChild<LLUICtrl>("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f);
+ getChild<LLUICtrl>("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f);
+
+ getChild<LLUICtrl>("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative));
+ 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());
}
{
- F32 offset_t = 0.f;
- struct f5 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mOffsetT;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t );
- identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexOffsetV")->setValue(editable ? offset_t : 0);
- getChild<LLUICtrl>("TexOffsetV")->setTentative(!identical);
+ bool identical_diff_offset_t = false;
+ bool identical_norm_offset_t = false;
+ bool identical_spec_offset_t = false;
+
+ F32 diff_offset_t = 0.0f;
+ F32 norm_offset_t = 0.0f;
+ F32 spec_offset_t = 0.0f;
+
+ LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t);
+ LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t);
+ LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t);
+
+ BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t);
+ BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t);
+ BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t);
+
+ getChild<LLUICtrl>("TexOffsetV")->setValue( editable ? diff_offset_t : 0.0f);
+ getChild<LLUICtrl>("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f);
+ getChild<LLUICtrl>("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f);
+
+ getChild<LLUICtrl>("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative));
+ 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());
}
// Texture rotation
{
- F32 rotation = 0.f;
- struct f6 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mRotation;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation );
- identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0);
- getChild<LLUICtrl>("TexRot")->setTentative(!identical);
- getChildView("TexRot")->setEnabled(editable);
- }
+ bool identical_diff_rotation = false;
+ bool identical_norm_rotation = false;
+ bool identical_spec_rotation = false;
- // Color swatch
- LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- LLColor4 color = LLColor4::white;
- if(mColorSwatch)
- {
- struct f7 : public LLSelectedTEGetFunctor<LLColor4>
- {
- LLColor4 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->getColor();
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, color );
-
- mColorSwatch->setOriginal(color);
- mColorSwatch->set(color, TRUE);
+ F32 diff_rotation = 0.f;
+ F32 norm_rotation = 0.f;
+ F32 spec_rotation = 0.f;
- mColorSwatch->setValid(editable);
- mColorSwatch->setEnabled( editable );
- mColorSwatch->setCanApplyImmediately( editable );
- }
- // Color transparency
- {
- getChildView("color trans")->setEnabled(editable);
- }
+ LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation);
+ LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation);
+ LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation);
- F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
- {
- getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
- getChildView("ColorTrans")->setEnabled(editable);
- }
+ BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation);
+ BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation);
+ BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation);
- {
- F32 glow = 0.f;
- struct f8 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->getGlow();
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow );
+ 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;
- getChild<LLUICtrl>("glow")->setValue(glow);
- getChildView("glow")->setEnabled(editable);
- getChild<LLUICtrl>("glow")->setTentative(!identical);
- getChildView("glow label")->setEnabled(editable);
+ 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));
+ getChild<LLUICtrl>("bumpyRot")->setTentative(LLSD(spec_rot_tentative));
- // Bump
- {
- F32 shinyf = 0.f;
- struct f9 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return (F32)(object->getTE(face)->getShiny());
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shinyf );
- LLCtrlSelectionInterface* combobox_shininess =
- childGetSelectionInterface("combobox shininess");
- if (combobox_shininess)
- {
- combobox_shininess->selectNthItem((S32)shinyf);
- }
- else
- {
- llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl;
- }
- getChildView("combobox shininess")->setEnabled(editable);
- getChild<LLUICtrl>("combobox shininess")->setTentative(!identical);
- getChildView("label shininess")->setEnabled(editable);
+ getChild<LLUICtrl>("TexRot")->setValue( editable ? diff_rot_deg : 0.0f);
+ getChild<LLUICtrl>("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f);
+ getChild<LLUICtrl>("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f);
}
{
- F32 bumpf = 0.f;
- struct f10 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return (F32)(object->getTE(face)->getBumpmap());
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpf );
- LLCtrlSelectionInterface* combobox_bumpiness =
- childGetSelectionInterface("combobox bumpiness");
- if (combobox_bumpiness)
- {
- combobox_bumpiness->selectNthItem((S32)bumpf);
- }
- else
- {
- llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
- }
- getChildView("combobox bumpiness")->setEnabled(editable);
- getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical);
- getChildView("label bumpiness")->setEnabled(editable);
+ F32 glow = 0.f;
+ bool identical_glow = 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);
}
- {
- F32 genf = 0.f;
- struct f11 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return (F32)(object->getTE(face)->getTexGen());
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, genf );
- S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT;
- LLCtrlSelectionInterface* combobox_texgen =
- childGetSelectionInterface("combobox texgen");
+ {
+ LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen");
if (combobox_texgen)
{
- combobox_texgen->selectNthItem(selected_texgen);
+ // Maps from enum to combobox entry index
+ combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1);
}
else
{
llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;
}
+
getChildView("combobox texgen")->setEnabled(editable);
getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
getChildView("tex gen")->setEnabled(editable);
- if (selected_texgen == 1)
+ if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)
{
- getChild<LLUICtrl>("TexScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() );
- getChild<LLUICtrl>("TexScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() );
-
// EXP-1507 (change label based on the mapping mode)
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter"));
}
else
- if (selected_texgen == 0) // FIXME: should not be magic numbers
+ if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT)
{
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face"));
}
}
{
- F32 fullbrightf = 0.f;
- struct f12 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return (F32)(object->getTE(face)->getFullbright());
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf );
+ U8 fullbright_flag = 0;
+ bool identical_fullbright = false;
+
+ LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright);
- getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)fullbrightf);
+ getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0));
getChildView("checkbox fullbright")->setEnabled(editable);
- getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical);
+ getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);
}
- // Repeats per meter label
+ // Repeats per meter
{
- getChildView("rpt")->setEnabled(editable);
+ F32 repeats_diff = 1.f;
+ F32 repeats_norm = 1.f;
+ F32 repeats_spec = 1.f;
+
+ bool identical_diff_repeats = false;
+ bool identical_norm_repeats = false;
+ bool identical_spec_repeats = false;
+
+ LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats);
+ LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats);
+ LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats);
+
+ LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
+ if (mComboTexGen)
+ {
+ S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
+ BOOL enabled = editable && (index != 1);
+ BOOL identical_repeats = true;
+ F32 repeats = 1.0f;
+
+ U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE;
+ switch (material_type)
+ {
+ default:
+ case MATTYPE_DIFFUSE:
+ {
+ 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_NORMAL:
+ {
+ enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
+ identical_repeats = identical_norm_repeats;
+ repeats = repeats_norm;
+ }
+ break;
+ }
+
+ BOOL repeats_tentative = !identical_repeats;
+
+ getChildView("rptctrl")->setEnabled(identical_planar_texgen ? FALSE : enabled);
+ getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 1.0f);
+ getChild<LLUICtrl>("rptctrl")->setTentative(LLSD(repeats_tentative));
+ }
}
- // Repeats per meter
+ // Materials
{
- F32 repeats = 1.f;
- struct f13 : public LLSelectedTEGetFunctor<F32>
+ LLMaterialPtr material;
+ LLSelectedTEMaterial::getCurrent(material, identical);
+
+ if (material && editable)
{
- F32 get(LLViewerObject* object, S32 face)
+ LL_DEBUGS("Materials: OnMatererialsLoaded:") << material->asLLSD() << LL_ENDL;
+
+ // Alpha
+ LLCtrlSelectionInterface* combobox_alphamode =
+ childGetSelectionInterface("combobox alphamode");
+ if (combobox_alphamode)
+ {
+ U32 alpha_mode = material->getDiffuseAlphaMode();
+
+ if (transparency > 0.f)
+ { //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+
+ if (!mIsAlpha)
+ { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ }
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ else
{
- U32 s_axis = VX;
- U32 t_axis = VY;
- // BUG: Only repeats along S axis
- // BUG: Only works for boxes.
- LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
- return object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
+ llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
}
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats );
-
- getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 0);
- getChild<LLUICtrl>("rptctrl")->setTentative(!identical);
- LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
- if (mComboTexGen)
+ getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff());
+ updateAlphaControls();
+
+ identical_planar_texgen = isIdenticalPlanarTexgen();
+
+ // Shiny (specular)
+ F32 offset_x, offset_y, repeat_x, repeat_y, rot;
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ texture_ctrl->setImageAssetID(material->getSpecularID());
+
+ if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE))
+ {
+ material->getSpecularOffset(offset_x,offset_y);
+ material->getSpecularRepeat(repeat_x,repeat_y);
+
+ if (identical_planar_texgen)
+ {
+ repeat_x *= 2.0f;
+ repeat_y *= 2.0f;
+ }
+
+ rot = material->getSpecularRotation();
+ getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
+ getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y);
+ getChild<LLUICtrl>("shinyRot")->setValue(rot*RAD_TO_DEG);
+ getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x);
+ getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y);
+ getChild<LLUICtrl>("glossiness")->setValue(material->getSpecularLightExponent());
+ getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity());
+
+ updateShinyControls(!material->getSpecularID().isNull(), true);
+ }
+
+ // Assert desired colorswatch color to match material AFTER updateShinyControls
+ // to avoid getting overwritten with the default on some UI state changes.
+ //
+ if (!material->getSpecularID().isNull())
+ {
+ getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(material->getSpecularLightColor());
+ getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);
+ }
+
+ // Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
+ // NORSPEC-103
+ LLRender::eTexIndex channel_to_edit = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP;
+
+ if ( ((channel_to_edit == LLRender::NORMAL_MAP) && material->getNormalID().isNull())
+ ||((channel_to_edit == LLRender::SPECULAR_MAP) && material->getSpecularID().isNull()))
+ {
+ channel_to_edit = LLRender::DIFFUSE_MAP;
+ }
+
+ LLSelectMgr::getInstance()->setTextureChannel(channel_to_edit);
+
+ // Bumpy (normal)
+ texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ texture_ctrl->setImageAssetID(material->getNormalID());
+
+ if (!material->getNormalID().isNull())
+ {
+ material->getNormalOffset(offset_x,offset_y);
+ material->getNormalRepeat(repeat_x,repeat_y);
+
+ if (identical_planar_texgen)
+ {
+ repeat_x *= 2.0f;
+ repeat_y *= 2.0f;
+ }
+
+ rot = material->getNormalRotation();
+ getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x);
+ getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y);
+ getChild<LLUICtrl>("bumpyRot")->setValue(rot*RAD_TO_DEG);
+ getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x);
+ getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y);
+
+ updateBumpyControls(!material->getNormalID().isNull(), true);
+ }
+ }
+ else
{
- BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1);
- getChildView("rptctrl")->setEnabled(enabled);
- getChildView("button apply")->setEnabled(enabled);
+ LLSelectMgr::getInstance()->setTextureChannel(LLRender::DIFFUSE_MAP);
}
}
@@ -934,14 +1407,11 @@ void LLPanelFace::getState()
getChildView("tex gen")->setEnabled(FALSE);
getChildView("label shininess")->setEnabled(FALSE);
getChildView("label bumpiness")->setEnabled(FALSE);
-
- getChildView("textbox autofix")->setEnabled(FALSE);
-
getChildView("button align")->setEnabled(FALSE);
- getChildView("button apply")->setEnabled(FALSE);
//getChildView("has media")->setEnabled(FALSE);
//getChildView("media info set")->setEnabled(FALSE);
-
+
+ updateVisibility();
// Set variable values for numeric expressions
LLCalc* calcp = LLCalc::getInstance();
@@ -958,6 +1428,7 @@ void LLPanelFace::getState()
void LLPanelFace::refresh()
{
+ LL_DEBUGS("Materials") << LL_ENDL;
getState();
}
@@ -977,6 +1448,11 @@ void LLPanelFace::onCommitColor(const LLSD& data)
sendColor();
}
+void LLPanelFace::onCommitShinyColor(const LLSD& data)
+{
+ LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
+}
+
void LLPanelFace::onCommitAlpha(const LLSD& data)
{
sendAlpha();
@@ -994,10 +1470,121 @@ void LLPanelFace::onSelectColor(const LLSD& data)
}
// static
+void LLPanelFace::onCommitMaterialsMedia(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->updateShinyControls(false,true);
+ self->updateBumpyControls(false,true);
+ self->updateUI();
+}
+
+// static
+void LLPanelFace::updateVisibility()
+{
+ LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
+ LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype");
+ LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess");
+ LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness");
+ if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness)
+ {
+ LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
+ return;
+ }
+ U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 material_type = combo_mattype->getCurrentIndex();
+ 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("combobox mattype")->setVisible(!show_media);
+ getChildView("rptctrl")->setVisible(true);
+
+ // Media controls
+ getChildView("media_info")->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("label maskcutoff")->setVisible(false);
+ getChildView("maskcutoff")->setVisible(false);
+ if (show_texture && !show_media)
+ {
+ 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);
+
+ // Specular map controls
+ getChildView("shinytexture control")->setVisible(show_shininess);
+ getChildView("combobox shininess")->setVisible(show_shininess);
+ getChildView("label shininess")->setVisible(show_shininess);
+ getChildView("label glossiness")->setVisible(false);
+ getChildView("glossiness")->setVisible(false);
+ getChildView("label environment")->setVisible(false);
+ getChildView("environment")->setVisible(false);
+ getChildView("label shinycolor")->setVisible(false);
+ getChildView("shinycolorswatch")->setVisible(false);
+ if (show_shininess)
+ {
+ 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);
+
+ // Normal map controls
+ if (show_bumpiness)
+ {
+ updateBumpyControls();
+ }
+ 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);
+
+
+}
+
+// static
+void LLPanelFace::onCommitMaterialType(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->updateShinyControls(false,true);
+ self->updateBumpyControls(false,true);
+ self->updateUI();
+}
+
+// static
void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendBump();
+
+ LLComboBox* mComboBumpiness = self->getChild<LLComboBox>("combobox bumpiness");
+ if(!mComboBumpiness)
+ return;
+
+ U32 bumpiness = mComboBumpiness->getCurrentIndex();
+
+ self->sendBump(bumpiness);
}
// static
@@ -1008,10 +1595,143 @@ void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata)
}
// static
+void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox)
+{
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL;
+ LLComboBox* comboShiny = getChild<LLComboBox>("combobox shininess");
+
+ if(mess_with_shiny_combobox)
+ {
+ if (!comboShiny)
+ {
+ return;
+ }
+ if (!shiny_texture_ID.isNull() && is_setting_texture)
+ {
+ if (!comboShiny->itemExists(USE_TEXTURE))
+ {
+ comboShiny->add(USE_TEXTURE);
+ }
+ comboShiny->setSimple(USE_TEXTURE);
+ }
+ else
+ {
+ if (comboShiny->itemExists(USE_TEXTURE))
+ {
+ comboShiny->remove(SHINY_TEXTURE);
+ comboShiny->selectFirstItem();
+ }
+ }
+ }
+
+ LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
+ LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype");
+ U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 material_type = combo_mattype->getCurrentIndex();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ U32 shiny_value = comboShiny->getCurrentIndex();
+ bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
+ getChildView("label glossiness")->setVisible(show_shinyctrls);
+ getChildView("glossiness")->setVisible(show_shinyctrls);
+ getChildView("label environment")->setVisible(show_shinyctrls);
+ getChildView("environment")->setVisible(show_shinyctrls);
+ getChildView("label shinycolor")->setVisible(show_shinyctrls);
+ getChildView("shinycolorswatch")->setVisible(show_shinyctrls);
+}
+
+// static
+void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox)
+{
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
+ LLComboBox* comboBumpy = getChild<LLComboBox>("combobox bumpiness");
+ if (!comboBumpy)
+ {
+ return;
+ }
+
+ if (mess_with_combobox)
+ {
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
+
+ if (!bumpy_texture_ID.isNull() && is_setting_texture)
+ {
+ if (!comboBumpy->itemExists(USE_TEXTURE))
+ {
+ comboBumpy->add(USE_TEXTURE);
+ }
+ comboBumpy->setSimple(USE_TEXTURE);
+ }
+ else
+ {
+ if (comboBumpy->itemExists(USE_TEXTURE))
+ {
+ comboBumpy->remove(BUMPY_TEXTURE);
+ comboBumpy->selectFirstItem();
+ }
+ }
+ }
+}
+
+// static
void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendShiny();
+
+
+ LLComboBox* mComboShininess = self->getChild<LLComboBox>("combobox shininess");
+ if(!mComboShininess)
+ return;
+
+ U32 shininess = mComboShininess->getCurrentIndex();
+
+ self->sendShiny(shininess);
+}
+
+// static
+void LLPanelFace::updateAlphaControls()
+{
+ LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode");
+ if (!comboAlphaMode)
+ {
+ return;
+ }
+ 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)
+ {
+ mat_media = combobox_matmedia->getCurrentIndex();
+ }
+
+ LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype");
+ U32 mat_type = MATTYPE_DIFFUSE;
+ if (combobox_mattype)
+ {
+ mat_type = combobox_mattype->getCurrentIndex();
+ }
+
+ show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL);
+ show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE);
+
+ getChildView("label maskcutoff")->setVisible(show_alphactrls);
+ getChildView("maskcutoff")->setVisible(show_alphactrls);
+}
+
+// static
+void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ self->updateAlphaControls();
+ LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode());
}
// static
@@ -1061,8 +1781,211 @@ void LLPanelFace::onSelectTexture(const LLSD& data)
{
LLSelectMgr::getInstance()->saveSelectedObjectTextures();
sendTexture();
+
+ LLGLenum image_format;
+ bool identical_image_format = false;
+ LLSelectedTE::getImageFormat(image_format, identical_image_format);
+
+ LLCtrlSelectionInterface* combobox_alphamode =
+ childGetSelectionInterface("combobox alphamode");
+
+ U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ if (combobox_alphamode)
+ {
+ switch (image_format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+ break;
+
+ case GL_RGB: break;
+ default:
+ {
+ llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl;
+ }
+ break;
+ }
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode());
+}
+
+void LLPanelFace::onCloseTexturePicker(const LLSD& data)
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ updateUI();
+}
+
+void LLPanelFace::onCommitSpecularTexture( const LLSD& data )
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ sendShiny(SHINY_TEXTURE);
+}
+
+void LLPanelFace::onCommitNormalTexture( const LLSD& data )
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ LLUUID nmap_id = getCurrentNormalMap();
+ sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
+}
+
+void LLPanelFace::onCancelSpecularTexture(const LLSD& data)
+{
+ U8 shiny = 0;
+ bool identical_shiny = false;
+ LLSelectedTE::getShiny(shiny, identical_shiny);
+ LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID();
+ shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE;
+ sendShiny(shiny);
+}
+
+void LLPanelFace::onCancelNormalTexture(const LLSD& data)
+{
+ U8 bumpy = 0;
+ bool identical_bumpy = false;
+ LLSelectedTE::getBumpmap(bumpy, identical_bumpy);
+ sendBump(bumpy);
}
+void LLPanelFace::onSelectSpecularTexture(const LLSD& data)
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ sendShiny(SHINY_TEXTURE);
+}
+
+void LLPanelFace::onSelectNormalTexture(const LLSD& data)
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ LLUUID nmap_id = getCurrentNormalMap();
+ sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU());
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV());
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU());
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV());
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 bumpy_scale_u = self->getCurrentBumpyScaleU();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ bumpy_scale_u *= 0.5f;
+ }
+ LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u);
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 bumpy_scale_v = self->getCurrentBumpyScaleV();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ bumpy_scale_v *= 0.5f;
+ }
+ LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v);
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 shiny_scale_u = self->getCurrentShinyScaleU();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ shiny_scale_u *= 0.5f;
+ }
+ LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u);
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 shiny_scale_v = self->getCurrentShinyScaleV();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ shiny_scale_v *= 0.5f;
+ }
+ LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v);
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD);
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD);
+}
+
+//static
+void LLPanelFace::onCommitMaterialGloss(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness());
+}
+
+//static
+void LLPanelFace::onCommitMaterialEnv(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity());
+}
+
+//static
+void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff());
+}
// static
void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
@@ -1073,15 +1996,67 @@ void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
// Commit the number of repeats per meter
// static
-void LLPanelFace::onClickApply(void* userdata)
+void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
- gFocusMgr.setKeyboardFocus( NULL );
+ LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
+ LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia");
+ LLComboBox* combo_mattype = self->getChild<LLComboBox>("combobox mattype");
+
+ U32 materials_media = combo_matmedia->getCurrentIndex();
+
+
+ U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? combo_mattype->getCurrentIndex() : 0;
+ F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
+
+ F32 obj_scale_s = 1.0f;
+ F32 obj_scale_t = 1.0f;
+
+ bool identical_scale_s = false;
+ bool identical_scale_t = false;
+
+ LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s);
+ LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t);
+
+ switch (material_type)
+ {
+ case MATTYPE_DIFFUSE:
+ {
+ LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
+ }
+ break;
+
+ case MATTYPE_NORMAL:
+ {
+ LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU");
+ LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV");
+
+ bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
+ bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
+
+ LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
+ LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
+ }
+ break;
- //F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get();
- F32 repeats_per_meter = (F32)self->getChild<LLUICtrl>("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get();
- LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
+ case MATTYPE_SPECULAR:
+ {
+ LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU");
+ LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV");
+
+ shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
+ shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
+
+ LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
+ LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
+ }
+ break;
+
+ default:
+ llassert(false);
+ break;
+ }
}
struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
@@ -1155,7 +2130,26 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
{
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+ LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL;
+ LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype");
+ if (!combo_mattype)
+ {
+ return;
+ }
+ U32 mattype = combo_mattype->getCurrentIndex();
+ std::string which_control="texture control";
+ switch (mattype)
+ {
+ case MATTYPE_SPECULAR:
+ which_control = "shinytexture control";
+ break;
+ case MATTYPE_NORMAL:
+ which_control = "bumpytexture control";
+ break;
+ // no default needed
+ }
+ LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL;
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(which_control);
if (texture_ctrl)
{
LLUUID obj_owner_id;
@@ -1185,3 +2179,212 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
}
}
}
+
+bool LLPanelFace::isIdenticalPlanarTexgen()
+{
+ LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
+ bool identical_texgen = false;
+ LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
+ return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
+}
+
+void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face)
+{
+ struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor<LLFace *>
+ {
+ LLFace* get(LLViewerObject* object, S32 te)
+ {
+ return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
+ }
+ } get_te_face_func;
+ identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return);
+}
+
+void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face)
+{
+ LLGLenum image_format;
+ struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor<LLGLenum>
+ {
+ LLGLenum get(LLViewerObject* object, S32 te_index)
+ {
+ LLViewerTexture* image = object->getTEImage(te_index);
+ return image ? image->getPrimaryFormat() : GL_RGB;
+ }
+ } get_glenum;
+ identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format);
+ image_format_to_return = image_format;
+}
+
+void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
+{
+ struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor<LLUUID>
+ {
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ LLUUID id;
+ LLViewerTexture* image = object->getTEImage(te_index);
+ if (image)
+ {
+ id = image->getID();
+ }
+
+ if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
+ {
+ LLTextureEntry *te = object->getTE(te_index);
+ if (te)
+ {
+ LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL;
+ if(!tex)
+ {
+ tex = LLViewerFetchedTexture::sDefaultImagep;
+ }
+ if (tex)
+ {
+ id = tex->getID();
+ }
+ }
+ }
+ return id;
+ }
+ } func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
+}
+
+void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material)
+{
+ struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr>
+ {
+ LLMaterialPtr get(LLViewerObject* object, S32 te_index)
+ {
+ return object->getTE(te_index)->getMaterialParams();
+ }
+ } func;
+ identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr);
+}
+
+void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical)
+{
+ struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ F32 repeats_s = 1.0f;
+ F32 repeats_t = 1.0f;
+ if (mat)
+ {
+ mat->getSpecularRepeat(repeats_s, repeats_t);
+ repeats_s /= object->getScale().mV[s_axis];
+ repeats_t /= object->getScale().mV[t_axis];
+ }
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } max_spec_repeats_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats);
+}
+
+void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical)
+{
+ struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ F32 repeats_s = 1.0f;
+ F32 repeats_t = 1.0f;
+ if (mat)
+ {
+ mat->getNormalRepeat(repeats_s, repeats_t);
+ repeats_s /= object->getScale().mV[s_axis];
+ repeats_t /= object->getScale().mV[t_axis];
+ }
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } max_norm_repeats_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats);
+}
+
+void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha)
+{
+ struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor<U8>
+ {
+ LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {}
+ LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {}
+ virtual ~LLSelectedTEGetDiffuseAlphaMode() {}
+
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ LLTextureEntry* tep = object->getTE(face);
+ if (tep)
+ {
+ LLMaterial* mat = tep->getMaterialParams().get();
+ if (mat)
+ {
+ diffuse_mode = mat->getDiffuseAlphaMode();
+ }
+ }
+
+ return diffuse_mode;
+ }
+ bool _isAlpha; // whether or not the diffuse texture selected contains alpha information
+ } get_diff_mode(diffuse_texture_has_alpha);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode);
+}
+
+void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical)
+{
+ struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ return object->getScale().mV[s_axis];
+ }
+
+ } scale_s_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s );
+}
+
+void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical)
+{
+ struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ return object->getScale().mV[t_axis];
+ }
+
+ } scale_t_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t );
+}
+
+void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical)
+{
+ struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
+ F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis];
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } 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 3b5a9b1398..42c1f6bd48 100755
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -29,6 +29,10 @@
#include "v4color.h"
#include "llpanel.h"
+#include "llmaterial.h"
+#include "llmaterialmgr.h"
+#include "lltextureentry.h"
+#include "llselectmgr.h"
class LLButton;
class LLCheckBoxCtrl;
@@ -42,6 +46,48 @@ class LLTextureCtrl;
class LLUICtrl;
class LLViewerObject;
class LLFloater;
+class LLMaterialID;
+
+// Represents an edit for use in replicating the op across one or more materials in the selection set.
+//
+// The apply function optionally performs the edit which it implements
+// as a functor taking Data that calls member func MaterialFunc taking SetValueType
+// on an instance of the LLMaterial class.
+//
+// boost who?
+//
+template<
+ typename DataType,
+ typename SetValueType,
+ void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
+class LLMaterialEditFunctor
+{
+public:
+ LLMaterialEditFunctor(const DataType& data) : _data(data) {}
+ virtual ~LLMaterialEditFunctor() {}
+ virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); }
+ DataType _data;
+};
+
+template<
+ typename DataType,
+ DataType (LLMaterial::*MaterialGetFunc)() >
+class LLMaterialGetFunctor
+{
+public:
+ LLMaterialGetFunctor() {}
+ virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); }
+};
+
+template<
+ typename DataType,
+ DataType (LLTextureEntry::*TEGetFunc)() >
+class LLTEGetFunctor
+{
+public:
+ LLTEGetFunctor() {}
+ virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); }
+};
class LLPanelFace : public LLPanel
{
@@ -61,11 +107,11 @@ protected:
void sendTextureInfo(); // applies and sends texture scale, offset, etc.
void sendColor(); // applies and sends color
void sendAlpha(); // applies and sends transparency
- void sendBump(); // applies and sends bump map
+ void sendBump(U32 bumpiness); // applies and sends bump map
void sendTexGen(); // applies and sends bump map
- void sendShiny(); // applies and sends shininess
+ void sendShiny(U32 shininess); // applies and sends shininess
void sendFullbright(); // applies and sends full bright
- void sendGlow();
+ void sendGlow();
void sendMedia();
// this function is to return TRUE if the drag should succeed.
@@ -74,25 +120,228 @@ protected:
void onCommitTexture(const LLSD& data);
void onCancelTexture(const LLSD& data);
void onSelectTexture(const LLSD& data);
+ void onCommitSpecularTexture(const LLSD& data);
+ void onCancelSpecularTexture(const LLSD& data);
+ void onSelectSpecularTexture(const LLSD& data);
+ void onCommitNormalTexture(const LLSD& data);
+ void onCancelNormalTexture(const LLSD& data);
+ void onSelectNormalTexture(const LLSD& data);
void onCommitColor(const LLSD& data);
+ void onCommitShinyColor(const LLSD& data);
void onCommitAlpha(const LLSD& data);
void onCancelColor(const LLSD& data);
void onSelectColor(const LLSD& data);
-
- static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);
- static void onCommitBump( LLUICtrl* ctrl, void* userdata);
+
+ void onCloseTexturePicker(const LLSD& data);
+
+ // Make UI reflect state of currently selected material (refresh)
+ // and UI mode (e.g. editing normal map v diffuse map)
+ //
+ void updateUI();
+
+ // Convenience func to determine if all faces in selection have
+ // identical planar texgen settings during edits
+ //
+ bool isIdenticalPlanarTexgen();
+
+ // Callback funcs for individual controls
+ //
+ static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialType( 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);
+ static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
+ static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata);
static void onCommitFullbright( LLUICtrl* ctrl, void* userdata);
- static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
- static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
-
- static void onClickApply(void*);
+ static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
+ static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
+ static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
static void onClickAutoFix(void*);
- static F32 valueGlow(LLViewerObject* object, S32 face);
+
+ static F32 valueGlow(LLViewerObject* object, S32 face);
private:
+ bool isAlpha() { return mIsAlpha; }
+
+ // Convenience funcs to keep the visual flack to a minimum
+ //
+ LLUUID getCurrentNormalMap();
+ LLUUID getCurrentSpecularMap();
+ U32 getCurrentShininess();
+ U32 getCurrentBumpiness();
+ U8 getCurrentDiffuseAlphaMode();
+ U8 getCurrentAlphaMaskCutoff();
+ U8 getCurrentEnvIntensity();
+ U8 getCurrentGlossiness();
+ F32 getCurrentBumpyRot();
+ F32 getCurrentBumpyScaleU();
+ F32 getCurrentBumpyScaleV();
+ F32 getCurrentBumpyOffsetU();
+ F32 getCurrentBumpyOffsetV();
+ F32 getCurrentShinyRot();
+ F32 getCurrentShinyScaleU();
+ F32 getCurrentShinyScaleV();
+ F32 getCurrentShinyOffsetU();
+ F32 getCurrentShinyOffsetV();
+
+ // Update visibility of controls to match current UI mode
+ // (e.g. materials vs media editing)
+ //
+ // Do NOT call updateUI from within this function.
+ //
+ 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! :)
+ //
+
+ // Update material parameters by applying 'edit_func' to selected TEs
+ //
+ template<
+ typename DataType,
+ typename SetValueType,
+ void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
+ static void edit(LLPanelFace* p, DataType data)
+ {
+ LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data);
+ struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor
+ {
+ LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp) : _panel(panel), _edit(editp) {}
+ virtual ~LLSelectedTEEditMaterial() {};
+ virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material)
+ {
+ if (_edit)
+ {
+ LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial());
+ llassert_always(new_material);
+
+ // Determine correct alpha mode for current diffuse texture
+ // (i.e. does it have an alpha channel that makes alpha mode useful)
+ //
+ U8 default_alpha_mode = (_panel->isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
+
+ // Default to matching expected state of UI
+ //
+ new_material->setDiffuseAlphaMode(current_material.isNull() ? default_alpha_mode : current_material->getDiffuseAlphaMode());
+
+ // Do "It"!
+ //
+ _edit->apply(new_material);
+
+ U32 new_alpha_mode = new_material->getDiffuseAlphaMode();
+ LLUUID new_normal_map_id = new_material->getNormalID();
+ LLUUID new_spec_map_id = new_material->getSpecularID();
+
+ bool is_default_blend_mode = (new_alpha_mode == default_alpha_mode);
+ bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull();
+
+ if (!is_need_material)
+ {
+ LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
+ LLMaterialMgr::getInstance()->remove(object->getID(),face);
+ new_material = NULL;
+ }
+ else
+ {
+ LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL;
+ LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material);
+ }
+
+ object->setTEMaterialParams(face, new_material);
+ return new_material;
+ }
+ return NULL;
+ }
+ LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit;
+ LLPanelFace* _panel;
+ } editor(p, &edit);
+ LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor);
+ }
+
+ template<
+ typename DataType,
+ typename ReturnType,
+ ReturnType (LLMaterial::* const MaterialGetFunc)() const >
+ static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value)
+ {
+ DataType data_value;
+ struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType>
+ {
+ GetTEMaterialVal(DataType default_value) : _default(default_value) {}
+ virtual ~GetTEMaterialVal() {}
+
+ DataType get(LLViewerObject* object, S32 face)
+ {
+ DataType ret = _default;
+ LLMaterialPtr material_ptr;
+ LLTextureEntry* tep = object ? object->getTE(face) : NULL;
+ if (tep)
+ {
+ material_ptr = tep->getMaterialParams();
+ if (!material_ptr.isNull())
+ {
+ ret = (material_ptr->*(MaterialGetFunc))();
+ }
+ }
+ return ret;
+ }
+ DataType _default;
+ } GetFunc(default_value);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value);
+ data_to_return = data_value;
+ }
+
+ template<
+ typename DataType,
+ typename ReturnType, // some kids just have to different...
+ ReturnType (LLTextureEntry::* const TEGetFunc)() const >
+ static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value)
+ {
+ DataType data_value;
+ struct GetTEVal : public LLSelectedTEGetFunctor<DataType>
+ {
+ GetTEVal(DataType default_value) : _default(default_value) {}
+ virtual ~GetTEVal() {}
+
+ DataType get(LLViewerObject* object, S32 face) {
+ LLTextureEntry* tep = object ? object->getTE(face) : NULL;
+ return tep ? ((tep->*(TEGetFunc))()) : _default;
+ }
+ DataType _default;
+ } GetTEValFunc(default_value);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value );
+ data_to_return = data_value;
+ }
+
+ // Update vis and enabling of specific subsets of controls based on material params
+ // (e.g. hide the spec controls if no spec texture is applied)
+ //
+ void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false);
+ void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false);
+ void updateAlphaControls();
+
/*
* Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object.
* If agent selects texture which is not allowed to be applied for the currently selected object,
@@ -100,6 +349,126 @@ private:
*/
void onTextureSelectionChanged(LLInventoryItem* itemp);
+ bool mIsAlpha;
+
+ /* These variables interlock processing of materials updates sent to
+ * the sim. mUpdateInFlight is set to flag that an update has been
+ * sent to the sim and not acknowledged yet, and cleared when an
+ * update is received from the sim. mUpdatePending is set when
+ * there's an update in flight and another UI change has been made
+ * that needs to be sent as a materials update, and cleared when the
+ * update is sent. This prevents the sim from getting spammed with
+ * update messages when, for example, the user holds down the
+ * up-arrow on a spinner, and avoids running afoul of its throttle.
+ */
+ bool mUpdateInFlight;
+ bool mUpdatePending;
+
+ #if defined(DEF_GET_MAT_STATE)
+ #undef DEF_GET_MAT_STATE
+ #endif
+
+ #if defined(DEF_GET_TE_STATE)
+ #undef DEF_GET_TE_STATE
+ #endif
+
+ #if defined(DEF_EDIT_MAT_STATE)
+ DEF_EDIT_MAT_STATE
+ #endif
+
+ // Accessors for selected TE material state
+ //
+ #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue) \
+ static void MaterialMemberFunc(DataType& data, bool& identical) \
+ { \
+ getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical,DefaultValue); \
+ }
+
+ // Mutators for selected TE material
+ //
+ #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc) \
+ static void MaterialMemberFunc(LLPanelFace* p,DataType data) \
+ { \
+ edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p,data); \
+ }
+
+ // Accessors for selected TE state proper (legacy settings etc)
+ //
+ #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue) \
+ static void TexEntryMemberFunc(DataType& data, bool& identical) \
+ { \
+ getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical,DefaultValue); \
+ }
+
+ class LLSelectedTEMaterial
+ {
+ public:
+ static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material);
+ static void getMaxSpecularRepeats(F32& repeats, bool& identical);
+ static void getMaxNormalRepeats(F32& repeats, bool& identical);
+ static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha);
+
+ DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null)
+ DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f)
+
+ DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f)
+
+ DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode);
+ DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff);
+
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation);
+
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation);
+
+ DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity);
+ DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent);
+
+ DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);
+ DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);
+ DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor);
+ };
+
+ class LLSelectedTE
+ {
+ public:
+
+ static void getFace(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 getObjectScaleS(F32& scale_s, bool& identical);
+ static void getObjectScaleT(F32& scale_t, bool& identical);
+ static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
+
+ DEF_GET_TE_STATE(U8,U8,getBumpmap,0)
+ DEF_GET_TE_STATE(U8,U8,getShiny,0)
+ DEF_GET_TE_STATE(U8,U8,getFullbright,0)
+ DEF_GET_TE_STATE(F32,F32,getRotation,0.0f)
+ DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f)
+ DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f)
+ DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f)
+ DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f)
+ DEF_GET_TE_STATE(F32,F32,getGlow,0.0f)
+ DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT)
+ DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white)
+ };
};
#endif
+
diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index 3ee0746412..18b85cc9c3 100755
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -428,13 +428,13 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world)
F32 LLPhysicsMotion::calculateVelocity_local()
{
const F32 world_to_model_scale = 100.0f;
- LLJoint *joint = mJointState->getJoint();
- const LLVector3 position_world = joint->getWorldPosition();
- const LLVector3 last_position_world = mPosition_world;
+ LLJoint *joint = mJointState->getJoint();
+ const LLVector3 position_world = joint->getWorldPosition();
+ const LLVector3 last_position_world = mPosition_world;
const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale;
- const LLVector3 velocity_world = positionchange_world;
- const F32 velocity_local = toLocal(velocity_world);
- return velocity_local;
+ const LLVector3 velocity_world = positionchange_world;
+ const F32 velocity_local = toLocal(velocity_world);
+ return velocity_local;
}
F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local)
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 4681efd3e5..0cbdbe16a3 100755
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -29,6 +29,7 @@
// file include
#define LLSELECTMGR_CPP
#include "llselectmgr.h"
+#include "llmaterialmgr.h"
// library includes
#include "llcachename.h"
@@ -103,7 +104,6 @@ const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f;
const S32 MAX_ACTION_QUEUE_SIZE = 20;
const S32 MAX_SILS_PER_FRAME = 50;
const S32 MAX_OBJECTS_PER_PACKET = 254;
-const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
//
// Globals
@@ -188,6 +188,7 @@ LLSelectMgr::LLSelectMgr()
mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE))
{
mTEMode = FALSE;
+ mTextureChannel = LLRender::DIFFUSE_MAP;
mLastCameraPos.clearVec();
sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness");
@@ -236,6 +237,8 @@ void LLSelectMgr::clearSelections()
mHighlightedObjects->deleteAllNodes();
mRectSelectedObjects.clear();
mGridObjects.deleteAllNodes();
+
+ LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP);
}
void LLSelectMgr::update()
@@ -815,6 +818,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
if (objectp->getNumTEs() > 0)
{
nodep->selectAllTEs(TRUE);
+ objectp->setAllTESelected(true);
}
else
{
@@ -843,6 +847,10 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
// check to see if object is already in list
LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
+ // Reset (in anticipation of being set to an appropriate value by panel refresh, if they're up)
+ //
+ setTextureChannel(LLRender::DIFFUSE_MAP);
+
// if not in list, add it
if (!nodep)
{
@@ -872,10 +880,12 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
else if (face == SELECT_ALL_TES)
{
nodep->selectAllTEs(TRUE);
+ objectp->setAllTESelected(true);
}
else if (0 <= face && face < SELECT_MAX_TES)
{
nodep->selectTE(face, TRUE);
+ objectp->setTESelected(face, true);
}
else
{
@@ -1095,6 +1105,7 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
// flag this object as selected
objectp->setSelected(TRUE);
+ objectp->setAllTESelected(true);
mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
@@ -1318,6 +1329,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
if (nodep->isTESelected(te))
{
nodep->selectTE(te, FALSE);
+ objectp->setTESelected(te, false);
}
else
{
@@ -2004,6 +2016,76 @@ void LLSelectMgr::selectionSetGlow(F32 glow)
mSelectedObjects->applyToObjects( &func2 );
}
+void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func)
+{
+ struct f1 : public LLSelectedTEFunctor
+ {
+ LLMaterialPtr mMaterial;
+ f1(LLSelectedTEMaterialFunctor* material_func) : _material_func(material_func) {}
+
+ bool apply(LLViewerObject* object, S32 face)
+ {
+ if (object && object->permModify() && _material_func)
+ {
+ LLTextureEntry* tep = object->getTE(face);
+ if (tep)
+ {
+ LLMaterialPtr current_material = tep->getMaterialParams();
+ _material_func->apply(object, face, tep, current_material);
+ }
+ }
+ return true;
+ }
+
+ LLSelectedTEMaterialFunctor* _material_func;
+ } func1(material_func);
+ mSelectedObjects->applyToTEs( &func1 );
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ }
+ return true;
+ }
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
+}
+
+void LLSelectMgr::selectionRemoveMaterial()
+{
+ struct f1 : public LLSelectedTEFunctor
+ {
+ bool apply(LLViewerObject* object, S32 face)
+ {
+ if (object->permModify())
+ {
+ LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
+ LLMaterialMgr::getInstance()->remove(object->getID(),face);
+ object->setTEMaterialParams(face, NULL);
+ }
+ return true;
+ }
+ } func1;
+ mSelectedObjects->applyToTEs( &func1 );
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ }
+ return true;
+ }
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
+}
+
//-----------------------------------------------------------------------------
// findObjectPermissions()
@@ -2425,19 +2507,66 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
continue;
}
- LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num];
LLVector3 object_scale = object->getScale();
+ LLVector3 diffuse_scale_ratio = selectNode->mTextureScaleRatios[te_num];
+
+ // We like these to track together. NORSPEC-96
+ //
+ LLVector3 normal_scale_ratio = diffuse_scale_ratio;
+ LLVector3 specular_scale_ratio = diffuse_scale_ratio;
// Apply new scale to face
if (planar)
{
- object->setTEScale(te_num, 1.f/object_scale.mV[s_axis]*scale_ratio.mV[s_axis],
- 1.f/object_scale.mV[t_axis]*scale_ratio.mV[t_axis]);
+ F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t);
+
+ LLTextureEntry* tep = object->getTE(te_num);
+
+ if (tep && !tep->getMaterialParams().isNull())
+ {
+ LLMaterialPtr orig = tep->getMaterialParams();
+ LLMaterialPtr p = new LLMaterial(orig->asLLSD());
+ p->setNormalRepeat(normal_scale_s, normal_scale_t);
+ p->setSpecularRepeat(specular_scale_s, specular_scale_t);
+
+ LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p);
+ }
}
else
{
- object->setTEScale(te_num, scale_ratio.mV[s_axis]*object_scale.mV[s_axis],
- scale_ratio.mV[t_axis]*object_scale.mV[t_axis]);
+
+ F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t);
+
+ LLTextureEntry* tep = object->getTE(te_num);
+
+ if (tep && !tep->getMaterialParams().isNull())
+ {
+ LLMaterialPtr orig = tep->getMaterialParams();
+
+ LLMaterialPtr p = new LLMaterial(orig->asLLSD());
+ p->setNormalRepeat(normal_scale_s, normal_scale_t);
+ p->setSpecularRepeat(specular_scale_s, specular_scale_t);
+
+ LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p);
+ }
}
send = send_to_sim;
}
@@ -4398,7 +4527,8 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
struct f : public LLSelectedNodeFunctor
{
EActionType mActionType;
- f(EActionType a) : mActionType(a) {}
+ LLSelectMgr* mManager;
+ f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {}
virtual bool apply(LLSelectNode* selectNode)
{
LLViewerObject* object = selectNode->getObject();
@@ -4445,10 +4575,10 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
}
selectNode->mSavedScale = object->getScale();
- selectNode->saveTextureScaleRatios();
+ selectNode->saveTextureScaleRatios(mManager->mTextureChannel);
return true;
}
- } func(action_type);
+ } func(action_type, this);
getSelection()->applyToNodes(&func);
mSavedSelectionBBox = getBBoxOfSelection();
@@ -5759,36 +5889,43 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)
}
}
-void LLSelectNode::saveTextureScaleRatios()
+void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
{
mTextureScaleRatios.clear();
+
if (mObject.notNull())
{
+
+ LLVector3 scale = mObject->getScale();
+
for (U8 i = 0; i < mObject->getNumTEs(); i++)
{
- F32 s,t;
+ F32 diffuse_s = 1.0f;
+ F32 diffuse_t = 1.0f;
+
+ LLVector3 v;
const LLTextureEntry* tep = mObject->getTE(i);
- tep->getScale(&s,&t);
- U32 s_axis = 0;
- U32 t_axis = 0;
+ if (!tep)
+ continue;
+ U32 s_axis = VX;
+ U32 t_axis = VY;
LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
- LLVector3 v;
- LLVector3 scale = mObject->getScale();
-
+ tep->getScale(&diffuse_s,&diffuse_t);
+
if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)
{
- v.mV[s_axis] = s*scale.mV[s_axis];
- v.mV[t_axis] = t*scale.mV[t_axis];
+ v.mV[s_axis] = diffuse_s*scale.mV[s_axis];
+ v.mV[t_axis] = diffuse_t*scale.mV[t_axis];
+ mTextureScaleRatios.push_back(v);
}
else
{
- v.mV[s_axis] = s/scale.mV[s_axis];
- v.mV[t_axis] = t/scale.mV[t_axis];
- }
-
- mTextureScaleRatios.push_back(v);
+ v.mV[s_axis] = diffuse_s/scale.mV[s_axis];
+ v.mV[t_axis] = diffuse_t/scale.mV[t_axis];
+ mTextureScaleRatios.push_back(v);
+ }
}
}
}
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index cc78e35869..d4b736640c 100755
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -43,10 +43,12 @@
#include "llpermissions.h"
#include "llcontrol.h"
#include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template
+#include "llmaterial.h"
#include <deque>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/signals2.hpp>
+#include <boost/make_shared.hpp> // boost::make_shared
class LLMessageSystem;
class LLViewerTexture;
@@ -83,6 +85,12 @@ struct LLSelectedTEFunctor
virtual bool apply(LLViewerObject* object, S32 face) = 0;
};
+struct LLSelectedTEMaterialFunctor
+{
+ virtual ~LLSelectedTEMaterialFunctor() {};
+ virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0;
+};
+
template <typename T> struct LLSelectedTEGetFunctor
{
virtual ~LLSelectedTEGetFunctor() {};
@@ -121,6 +129,8 @@ typedef enum e_selection_type
SELECT_TYPE_HUD
}ESelectType;
+const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
+
// Contains information about a selected object, particularly which TEs are selected.
class LLSelectNode
{
@@ -143,7 +153,7 @@ public:
// *NOTE: invalidate stored textures and colors when # faces change
void saveColors();
void saveTextures(const uuid_vec_t& textures);
- void saveTextureScaleRatios();
+ void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
@@ -510,6 +520,11 @@ public:
void saveSelectedObjectColors();
void saveSelectedObjectTextures();
+ // Sets which texture channel to query for scale and rot of display
+ // and depends on UI state of LLPanelFace when editing
+ void setTextureChannel(LLRender::eTexIndex texIndex) { mTextureChannel = texIndex; }
+ LLRender::eTexIndex getTextureChannel() { return mTextureChannel; }
+
void selectionUpdatePhysics(BOOL use_physics);
void selectionUpdateTemporary(BOOL is_temporary);
void selectionUpdatePhantom(BOOL is_ghost);
@@ -540,6 +555,8 @@ public:
void selectionSetClickAction(U8 action);
void selectionSetIncludeInSearch(bool include_in_search);
void selectionSetGlow(const F32 glow);
+ void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func);
+ void selectionRemoveMaterial();
void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE);
void selectionSetObjectName(const std::string& name);
@@ -771,6 +788,7 @@ private:
EGridMode mGridMode;
BOOL mTEMode; // render te
+ LLRender::eTexIndex mTextureChannel; // diff, norm, or spec, depending on UI editing mode
LLVector3d mSelectionCenterGlobal;
LLBBox mSelectionBBox;
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index e082859767..e5637bcaf7 100755
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -231,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
{
gAgentCamera.changeCameraToDefault();
gAgentCamera.resetView();
- }
+ }
}
}
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 762f557a80..b0a6b9cf91 100755
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -47,7 +47,7 @@ public:
virtual ~LLSidepanelAppearance();
/*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onOpen(const LLSD& key);
void refreshCurrentOutfitName(const std::string& name = "");
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index f85e855fd3..941c578783 100755
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1498,6 +1498,8 @@ BOOL LLSpatialGroup::rebound()
if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0)
{
LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
+
+ //rebound single child
group->rebound();
//copy single child's bounding box
@@ -1506,10 +1508,11 @@ BOOL LLSpatialGroup::rebound()
mExtents[0] = group->mExtents[0];
mExtents[1] = group->mExtents[1];
+ //treat this node as a "chute" to a deeper level of the tree
group->setState(SKIP_FRUSTUM_CHECK);
}
else if (mOctreeNode->isLeaf())
- { //copy object bounding box if this is a leaf
+ { //copy object bounding box if this is a leaf
boundObjects(TRUE, mExtents[0], mExtents[1]);
mBounds[0] = mObjectBounds[0];
mBounds[1] = mObjectBounds[1];
@@ -1518,14 +1521,17 @@ BOOL LLSpatialGroup::rebound()
{
LLVector4a& newMin = mExtents[0];
LLVector4a& newMax = mExtents[1];
+
+ //get bounding box of first child
LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
group->clearState(SKIP_FRUSTUM_CHECK);
group->rebound();
+
//initialize to first child
newMin = group->mExtents[0];
newMax = group->mExtents[1];
- //first, rebound children
+ //rebound remaining children, expanding bounding box to encompass children
for (U32 i = 1; i < mOctreeNode->getChildCount(); i++)
{
group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0);
@@ -2506,7 +2512,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
}
}
-void pushBufferVerts(LLSpatialGroup* group, U32 mask)
+void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
{
if (group->mSpatialPartition->mRenderByGroup)
{
@@ -2515,7 +2521,10 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin());
LLRenderPass::applyModelMatrix(*params);
- pushBufferVerts(group->mVertexBuffer, mask);
+ if (push_alpha)
+ {
+ pushBufferVerts(group->mVertexBuffer, mask);
+ }
for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
{
@@ -2529,10 +2538,10 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
}
}
}
- else
+ /*else
{
- drawBox(group->mBounds[0], group->mBounds[1]);
- }
+ //drawBox(group->mBounds[0], group->mBounds[1]);
+ }*/
}
void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
@@ -2705,18 +2714,54 @@ void renderOctree(LLSpatialGroup* group)
// drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
}
+std::set<LLSpatialGroup*> visible_selected_groups;
+
void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
{
- LLGLEnable blend(GL_BLEND);
+ /*LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
LLGLEnable cull(GL_CULL_FACE);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);*/
- BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
+ /*BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
!group->isEmpty();
+
if (render_objects)
{
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+
+ LLGLDisable blend(GL_BLEND);
+ gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
+ pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glLineWidth(4.f);
+ gGL.diffuseColor4f(0.f, 0.5f, 0.f, 1.f);
+ pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
+ glLineWidth(1.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ bool selected = false;
+
+ for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
+ {
+ selected = true;
+ break;
+ }
+ }
+
+ if (selected)
+ { //store for rendering occlusion volume as overlay
+ visible_selected_groups.insert(group);
+ }
+ }*/
+
+ /*if (render_objects)
+ {
LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
@@ -2740,6 +2785,59 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
+
+ bool selected = false;
+
+ for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
+ {
+ selected = true;
+ break;
+ }
+ }
+
+ if (selected)
+ { //store for rendering occlusion volume as overlay
+ visible_selected_groups.insert(group);
+ }
+ }
+ }*/
+}
+
+void renderXRay(LLSpatialGroup* group, LLCamera* camera)
+{
+ BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
+ !group->isEmpty();
+
+ if (render_objects)
+ {
+ pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
+
+ bool selected = false;
+
+ for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
+ {
+ selected = true;
+ break;
+ }
+ }
+
+ if (selected)
+ { //store for rendering occlusion volume as overlay
+
+ if (!group->mSpatialPartition->isBridge())
+ {
+ visible_selected_groups.insert(group);
+ }
+ else
+ {
+ visible_selected_groups.insert(group->mSpatialPartition->asBridge()->getSpatialGroup());
+ }
}
}
}
@@ -3039,9 +3137,9 @@ void renderNormals(LLDrawable* drawablep)
gGL.vertex3fv(face.mPositions[j].getF32ptr());
gGL.vertex3fv(p.getF32ptr());
- if (face.mBinormals)
+ if (face.mTangents)
{
- n.setMul(face.mBinormals[j], scale);
+ n.setMul(face.mTangents[j], scale);
p.setAdd(face.mPositions[j], n);
gGL.diffuseColor4f(0,1,1,1);
@@ -3888,11 +3986,17 @@ void renderRaycast(LLDrawable* drawablep)
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
- LLVector3 start, end;
+ LLVector4a start, end;
if (transform)
{
- start = vobj->agentPositionToVolume(gDebugRaycastStart);
- end = vobj->agentPositionToVolume(gDebugRaycastEnd);
+ LLVector3 v_start(gDebugRaycastStart.getF32ptr());
+ LLVector3 v_end(gDebugRaycastEnd.getF32ptr());
+
+ v_start = vobj->agentPositionToVolume(v_start);
+ v_end = vobj->agentPositionToVolume(v_end);
+
+ start.load3(v_start.mV);
+ end.load3(v_end.mV);
}
else
{
@@ -3900,11 +4004,8 @@ void renderRaycast(LLDrawable* drawablep)
end = gDebugRaycastEnd;
}
- LLVector4a starta, enda;
- starta.load3(start.mV);
- enda.load3(end.mV);
LLVector4a dir;
- dir.setSub(enda, starta);
+ dir.setSub(end, start);
gGL.flush();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -3927,7 +4028,7 @@ void renderRaycast(LLDrawable* drawablep)
((LLVolumeFace*) &face)->createOctree();
}
- LLRenderOctreeRaycast render(starta, dir, &t);
+ LLRenderOctreeRaycast render(start, dir, &t);
render.traverse(face.mOctree);
}
@@ -3952,10 +4053,18 @@ void renderRaycast(LLDrawable* drawablep)
// draw intersection point
gGL.pushMatrix();
gGL.loadMatrix(gGLModelView);
- LLVector3 translate = gDebugRaycastIntersection;
+ LLVector3 translate(gDebugRaycastIntersection.getF32ptr());
gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);
LLCoordFrame orient;
- orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal);
+ LLVector4a debug_binormal;
+
+ debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent);
+ debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]);
+
+ LLVector3 normal(gDebugRaycastNormal.getF32ptr());
+ LLVector3 binormal(debug_binormal.getF32ptr());
+
+ orient.lookDir(normal, binormal);
LLMatrix4 rotation;
orient.getRotMatrixToParent(rotation);
gGL.multMatrix((float*)rotation.mMatrix);
@@ -4199,6 +4308,48 @@ public:
}
};
+class LLOctreeRenderXRay : public LLOctreeTraveler<LLDrawable>
+{
+public:
+ LLCamera* mCamera;
+ LLOctreeRenderXRay(LLCamera* camera): mCamera(camera) {}
+
+ virtual void traverse(const LLSpatialGroup::OctreeNode* node)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
+
+ if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))
+ {
+ node->accept(this);
+ stop_glerror();
+
+ for (U32 i = 0; i < node->getChildCount(); i++)
+ {
+ traverse(node->getChild(i));
+ stop_glerror();
+ }
+
+ //render visibility wireframe
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
+ {
+ group->rebuildGeom();
+ group->rebuildMesh();
+
+ gGL.flush();
+ gGL.pushMatrix();
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ renderXRay(group, mCamera);
+ stop_glerror();
+ gGLLastMatrix = NULL;
+ gGL.popMatrix();
+ }
+ }
+ }
+
+ virtual void visit(const LLSpatialGroup::OctreeNode* node) {}
+
+};
class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler<LLDrawable>
{
@@ -4426,6 +4577,26 @@ void LLSpatialPartition::renderDebug()
LLOctreeRenderNonOccluded render_debug(camera);
render_debug.traverse(mOctree);
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
+ {
+ {
+ LLGLEnable cull(GL_CULL_FACE);
+
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ gGL.diffuseColor4f(0.5f, 0.0f, 0, 0.25f);
+
+ LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(-1.f, -1.f);
+
+ LLOctreeRenderXRay xray(camera);
+ xray.traverse(mOctree);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+ }
if (LLGLSLShader::sNoFixedFunction)
{
gDebugProgram.unbind();
@@ -4457,28 +4628,30 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)
return TRUE;
}
+LL_ALIGN_PREFIX(16)
class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
{
public:
- LLVector3 mStart;
- LLVector3 mEnd;
+ LL_ALIGN_16(LLVector4a mStart);
+ LL_ALIGN_16(LLVector4a mEnd);
+
S32 *mFaceHit;
- LLVector3 *mIntersection;
+ LLVector4a *mIntersection;
LLVector2 *mTexCoord;
- LLVector3 *mNormal;
- LLVector3 *mBinormal;
+ LLVector4a *mNormal;
+ LLVector4a *mTangent;
LLDrawable* mHit;
BOOL mPickTransparent;
- LLOctreeIntersect(LLVector3 start, LLVector3 end, BOOL pick_transparent,
- S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal)
+ LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent,
+ S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
: mStart(start),
mEnd(end),
mFaceHit(face_hit),
mIntersection(intersection),
mTexCoord(tex_coord),
mNormal(normal),
- mBinormal(binormal),
+ mTangent(tangent),
mHit(NULL),
mPickTransparent(pick_transparent)
{
@@ -4509,23 +4682,22 @@ public:
size = group->mBounds[1];
center = group->mBounds[0];
- LLVector3 local_start = mStart;
- LLVector3 local_end = mEnd;
+ LLVector4a local_start = mStart;
+ LLVector4a local_end = mEnd;
if (group->mSpatialPartition->isBridge())
{
LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix();
local_matrix.invert();
-
- local_start = mStart * local_matrix;
- local_end = mEnd * local_matrix;
- }
- LLVector4a start, end;
- start.load3(local_start.mV);
- end.load3(local_end.mV);
+ LLMatrix4a local_matrix4a;
+ local_matrix4a.loadu(local_matrix);
- if (LLLineSegmentBoxIntersect(start, end, center, size))
+ local_matrix4a.affineTransform(mStart, local_start);
+ local_matrix4a.affineTransform(mEnd, local_end);
+ }
+
+ if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))
{
check(child);
}
@@ -4556,14 +4728,14 @@ public:
if (vobj)
{
- LLVector3 intersection;
+ LLVector4a intersection;
bool skip_check = false;
if (vobj->isAvatar())
{
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools))
{
- LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal);
+ LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
if (hit)
{
mEnd = intersection;
@@ -4579,7 +4751,7 @@ public:
}
}
- if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))
+ if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
{
mEnd = intersection; // shorten ray so we only find CLOSER hits
if (mIntersection)
@@ -4594,19 +4766,19 @@ public:
return false;
}
-};
+} LL_ALIGN_POSTFIX(16);
-LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit, // return the face hit
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at 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, face_hit, intersection, tex_coord, normal, bi_normal);
+ LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
LLDrawable* drawable = intersect.check(mOctree);
return drawable;
@@ -4632,7 +4804,13 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mGroup(NULL),
mFace(NULL),
mDistance(0.f),
- mDrawMode(LLRender::TRIANGLES)
+ mDrawMode(LLRender::TRIANGLES),
+ mMaterial(NULL),
+ mShaderMask(0),
+ mSpecColor(1.0f, 1.0f, 1.0f, 0.5f),
+ mEnvIntensity(0.0f),
+ mAlphaMaskCutoff(0.5f),
+ mDiffuseAlphaMode(0)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index b1706d9d35..9732be90af 100755
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -112,6 +112,7 @@ public:
U32 mOffset;
BOOL mFullbright;
U8 mBump;
+ U8 mShiny;
BOOL mParticle;
F32 mPartSize;
F32 mVSize;
@@ -119,6 +120,18 @@ 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;
+ LLPointer<LLViewerTexture> mSpecularMap;
+ const LLMatrix4* mSpecularMapMatrix;
+ LLPointer<LLViewerTexture> mNormalMap;
+ const LLMatrix4* mNormalMapMatrix;
+ LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
+ F32 mEnvIntensity;
+ F32 mAlphaMaskCutoff;
+ U8 mDiffuseAlphaMode;
+
struct CompareTexture
{
@@ -169,7 +182,7 @@ public:
}
};
-
+
struct CompareBump
{
bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
@@ -191,7 +204,7 @@ public:
};
};
-LL_ALIGN_PREFIX(16)
+LL_ALIGN_PREFIX(64)
class LLSpatialGroup : public LLOctreeListener<LLDrawable>
{
friend class LLSpatialPartition;
@@ -477,13 +490,13 @@ public:
LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp);
- LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit, // return the face hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
@@ -739,7 +752,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
- void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE);
+ void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
};
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 84d42c6345..f2b0e0e269 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -645,7 +645,7 @@ bool idle_startup()
gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
}
#endif
-
+
if (gAudiop)
{
#if LL_WINDOWS
diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp
index f8c1bca8ae..dbbe331954 100755
--- a/indra/newview/lltextureatlas.cpp
+++ b/indra/newview/lltextureatlas.cpp
@@ -71,7 +71,7 @@ LLTextureAtlas::~LLTextureAtlas()
//virtual
S8 LLTextureAtlas::getType() const
{
- return LLViewerTexture::ATLAS_TEXTURE ;
+ return 0; //LLViewerTexture::ATLAS_TEXTURE ;
}
void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset)
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 305f6fca0f..36a7aeb590 100755
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -568,8 +568,11 @@ bool LLTextureCacheRemoteWorker::doWrite()
idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry.
if(idx >= 0)
{
- //write to the fast cache.
- llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
+ // (almost always) write to the fast cache.
+ if (mRawImage->getDataSize())
+ {
+ llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
+ }
}
}
else
@@ -1895,10 +1898,17 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
{
//rescale image if needed
+ if (raw.isNull() || !raw->getData())
+ {
+ llerrs << "Attempted to write NULL raw image to fastcache" << llendl;
+ return false;
+ }
+
S32 w, h, c;
w = raw->getWidth();
h = raw->getHeight();
c = raw->getComponents();
+
S32 i = 0 ;
while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index e3fc957fd2..deaacc4975 100755
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -24,7 +24,7 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLTEXTURECACHE_
+#ifndef LL_LLTEXTURECACHE_H
#define LL_LLTEXTURECACHE_H
#include "lldir.h"
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index e2d0fdf357..4676f7b251 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -144,7 +144,7 @@ public:
static void onBtnCancel( void* userdata );
void onBtnPipette( );
//static void onBtnRevert( void* userdata );
- static void onBtnWhite( 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);
@@ -165,7 +165,6 @@ protected:
LLUUID mImageAssetID; // Currently selected texture
LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null.
- LLUUID mWhiteImageAssetID;
LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory.
LLUUID mOriginalImageAssetID;
@@ -208,8 +207,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
: LLFloater(LLSD()),
mOwner( owner ),
mImageAssetID( owner->getImageAssetID() ),
- mFallbackImage( fallback_image ),
- mWhiteImageAssetID( gSavedSettings.getString( "UIImgWhiteUUID" ) ),
+ mFallbackImage( fallback_image ),
mOriginalImageAssetID(owner->getImageAssetID()),
mLabel(label),
mTentativeLabel(NULL),
@@ -426,7 +424,7 @@ BOOL LLFloaterTexturePicker::postBuild()
childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
- childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this);
+ childSetAction("Blank", LLFloaterTexturePicker::onBtnBlank,this);
childSetCommitCallback("show_folders_check", onShowFolders, this);
@@ -581,7 +579,7 @@ void LLFloaterTexturePicker::draw()
}
getChildView("Default")->setEnabled(mImageAssetID != mOwner->getDefaultImageAssetID());
- getChildView("Blank")->setEnabled(mImageAssetID != mWhiteImageAssetID );
+ getChildView("Blank")->setEnabled(mImageAssetID != mOwner->getBlankImageAssetID());
getChildView("None")->setEnabled(mOwner->getAllowNoTexture() && !mImageAssetID.isNull() );
LLFloater::draw();
@@ -721,11 +719,11 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
}
// static
-void LLFloaterTexturePicker::onBtnWhite(void* userdata)
+void LLFloaterTexturePicker::onBtnBlank(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
self->setCanApply(true, true);
- self->setImageID( self->mWhiteImageAssetID );
+ self->setImageID( self->mOwner->getBlankImageAssetID() );
self->commitIfImmediateSet();
}
@@ -1042,6 +1040,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mDragCallback(NULL),
mDropCallback(NULL),
mOnCancelCallback(NULL),
+ mOnCloseCallback(NULL),
mOnSelectCallback(NULL),
mBorderColor( p.border_color() ),
mAllowNoTexture( FALSE ),
@@ -1056,6 +1055,12 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mDefaultImageName(p.default_image_name),
mFallbackImage(p.fallback_image)
{
+
+ // Default of defaults is white image for diff tex
+ //
+ LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) );
+ setBlankImageAssetID( whiteImage );
+
setAllowNoTexture(p.allow_no_texture);
setCanApplyImmediately(p.can_apply_immediately);
mCommitOnSelection = !p.no_commit_on_selection;
@@ -1292,6 +1297,10 @@ void LLTextureCtrl::onFloaterClose()
if (floaterp)
{
+ if (mOnCloseCallback)
+ {
+ mOnCloseCallback(this,LLSD());
+ }
floaterp->setOwner(NULL);
}
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 599d9c70c5..ad79042ef1 100755
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -126,6 +126,7 @@ public:
// LLTextureCtrl interface
void showPicker(BOOL take_focus);
+ bool isPickerShown() { return !mFloaterHandle.isDead(); }
void setLabel(const std::string& label);
void setLabelWidth(S32 label_width) {mLabelWidth =label_width;}
const std::string& getLabel() const { return mLabel; }
@@ -145,6 +146,9 @@ public:
const std::string& getDefaultImageName() const { return mDefaultImageName; }
+ void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
+ const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
+
void setCaption(const std::string& caption);
void setCanApplyImmediately(BOOL b);
@@ -174,7 +178,7 @@ public:
void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; }
void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; }
-
+ void setOnCloseCallback(commit_callback_t cb) { mOnCloseCallback = cb; }
void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; }
/*
@@ -195,12 +199,14 @@ private:
drag_n_drop_callback mDropCallback;
commit_callback_t mOnCancelCallback;
commit_callback_t mOnSelectCallback;
+ commit_callback_t mOnCloseCallback;
texture_selected_callback mOnTextureSelectedCallback;
LLPointer<LLViewerFetchedTexture> mTexturep;
LLUIColor mBorderColor;
LLUUID mImageItemID;
LLUUID mImageAssetID;
LLUUID mDefaultImageAssetID;
+ LLUUID mBlankImageAssetID;
LLUIImagePtr mFallbackImage;
std::string mDefaultImageName;
LLHandle<LLFloater> mFloaterHandle;
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 094694dc06..3da934b148 100755
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -400,7 +400,7 @@ void audio_update_volume(bool force_update)
gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
if(!LLViewerCamera::getInstance()->cameraUnderWater())
- gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
+ gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
else
gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelUnderwaterRolloff"));
@@ -494,18 +494,18 @@ void audio_update_wind(bool force_update)
LLViewerRegion* region = gAgent.getRegion();
if (region)
{
- // Scale down the contribution of weather-simulation wind to the
- // ambient wind noise. Wind velocity averages 3.5 m/s, with gusts to 7 m/s
- // whereas steady-state avatar walk velocity is only 3.2 m/s.
- // Without this the world feels desolate on first login when you are
- // standing still.
- static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);
- LLVector3 scaled_wind_vec = gWindVec * wind_level;
-
- // Mix in the avatar's motion, subtract because when you walk north,
- // the apparent wind moves south.
- LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity();
-
+ // Scale down the contribution of weather-simulation wind to the
+ // ambient wind noise. Wind velocity averages 3.5 m/s, with gusts to 7 m/s
+ // whereas steady-state avatar walk velocity is only 3.2 m/s.
+ // Without this the world feels desolate on first login when you are
+ // standing still.
+ static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);
+ LLVector3 scaled_wind_vec = gWindVec * wind_level;
+
+ // Mix in the avatar's motion, subtract because when you walk north,
+ // the apparent wind moves south.
+ LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity();
+
// rotate the wind vector to be listener (agent) relative
gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal( final_wind_vec );
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index a62f73deef..afbb59e723 100755
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -401,6 +401,25 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)
return true;
}
+// This looks a great deal like handleRenderDeferredChanged because
+// Advanced Lighting (Materials) implies bumps and shiny so disabling
+// bumps should further disable that feature.
+//
+static bool handleRenderBumpChanged(const LLSD& newval)
+{
+ LLRenderTarget::sUseFBO = newval.asBoolean();
+ if (gPipeline.isInit())
+ {
+ gPipeline.updateRenderBump();
+ gPipeline.updateRenderDeferred();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ gPipeline.resetVertexBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ }
+ return true;
+}
+
static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)
{
LLVOAvatar::sUseImpostors = newvalue.asBoolean();
@@ -629,7 +648,7 @@ void settings_setup_listeners()
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(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));
gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
gSavedSettings.getControl("RenderUseImpostors")->getSignal()->connect(boost::bind(&handleRenderUseImpostorsChanged, _2));
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index cf59e67955..f90b35a7bd 100755
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -98,6 +98,7 @@ BOOL gDepthDirty = FALSE;
BOOL gResizeScreenTexture = FALSE;
BOOL gWindowResized = FALSE;
BOOL gSnapshot = FALSE;
+BOOL gShaderProfileFrame = FALSE;
U32 gRecentFrameCount = 0; // number of 'recent' frames
LLFrameTimer gRecentFPSTime;
@@ -114,7 +115,8 @@ void render_disconnected_background();
void display_startup()
{
- if ( !gViewerWindow->getActive()
+ if ( !gViewerWindow
+ || !gViewerWindow->getActive()
|| !gViewerWindow->getWindow()->getVisible()
|| gViewerWindow->getWindow()->getMinimized() )
{
@@ -125,7 +127,14 @@ void display_startup()
// Update images?
//gImageList.updateImages(0.01f);
- LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
+
+ // Written as branch to appease GCC which doesn't like different
+ // pointer types across ternary ops
+ //
+ if (!LLViewerFetchedTexture::sWhiteImagep.isNull())
+ {
+ LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
+ }
LLGLSDefault gls_default;
@@ -147,10 +156,12 @@ void display_startup()
LLGLSUIDefault gls_ui;
gPipeline.disableLights();
+ if (gViewerWindow)
gViewerWindow->setup2DRender();
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
gGL.color4f(1,1,1,1);
+ if (gViewerWindow)
gViewerWindow->draw();
gGL.flush();
@@ -159,7 +170,9 @@ void display_startup()
LLGLState::checkStates();
LLGLState::checkTextureChannels();
+ if (gViewerWindow && gViewerWindow->getWindow())
gViewerWindow->getWindow()->swapBuffers();
+
glClear(GL_DEPTH_BUFFER_BIT);
}
@@ -340,6 +353,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
return;
}
+
+ if (gShaderProfileFrame)
+ {
+ LLGLSLShader::initProfile();
+ }
+
//LLGLState::verify(FALSE);
/////////////////////////////////////////////////
@@ -654,6 +673,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
static LLCullResult result;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
stop_glerror();
@@ -860,7 +880,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
//}
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
-
+
LLGLState::checkStates();
LLGLState::checkClientArrays();
@@ -1018,6 +1038,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
gShiftFrame = false;
+
+ if (gShaderProfileFrame)
+ {
+ gShaderProfileFrame = FALSE;
+ LLGLSLShader::finishProfile();
+ }
}
void render_hud_attachments()
@@ -1037,6 +1063,7 @@ void render_hud_attachments()
if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
{
+ LLPipeline::sRenderingHUDs = TRUE;
LLCamera hud_cam = *LLViewerCamera::getInstance();
hud_cam.setOrigin(-1.f,0,0);
hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
@@ -1081,10 +1108,13 @@ 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_MASK);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
@@ -1109,6 +1139,7 @@ void render_hud_attachments()
gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
}
LLPipeline::sUseOcclusion = use_occlusion;
+ LLPipeline::sRenderingHUDs = FALSE;
}
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index cc715ae21d..351d81e08f 100755
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -257,7 +257,7 @@ class AddFavoriteLandmarkCallback : public LLInventoryCallback
public:
AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
-
+
private:
void fire(const LLUUID& inv_item);
@@ -286,13 +286,13 @@ public:
// virtual
void fire(const LLUUID& item_id)
- {
+{
mFireFunc(item_id);
}
// virtual
~LLBoostFuncInventoryCallback()
- {
+{
mDestroyFunc();
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index beca08203f..5e2f05f468 100755
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -147,6 +147,8 @@ void handle_test_load_url(void*);
//extern BOOL gDebugAvatarRotation;
extern BOOL gDebugClicks;
extern BOOL gDebugWindowProc;
+extern BOOL gShaderProfileFrame;
+
//extern BOOL gDebugTextEditorTips;
//extern BOOL gDebugSelectMgr;
@@ -291,6 +293,7 @@ void request_friendship(const LLUUID& agent_id);
// Tools menu
void handle_selected_texture_info(void*);
+void handle_selected_material_info();
void handle_dump_followcam(void*);
void handle_viewer_enable_message_log(void*);
@@ -1189,28 +1192,6 @@ class LLAdvancedCheckWireframe : public view_listener_t
}
};
-//////////////////////
-// TEXTURE ATLAS //
-//////////////////////
-
-class LLAdvancedToggleTextureAtlas : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerTexture::sUseTextureAtlas = !LLViewerTexture::sUseTextureAtlas;
- gSavedSettings.setBOOL("EnableTextureAtlas", LLViewerTexture::sUseTextureAtlas) ;
- return true;
- }
-};
-
-class LLAdvancedCheckTextureAtlas : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLViewerTexture::sUseTextureAtlas; // <-- make this using LLCacheControl
- return new_value;
- }
-};
//////////////////////////
// DUMP SCRIPTED CAMERA //
@@ -6463,7 +6444,7 @@ class LLAttachmentDetachFromPoint : public view_listener_t
LLViewerObject *attached_object = (*iter);
ids_to_remove.push_back(attached_object->getAttachmentItemID());
}
- }
+ }
if (!ids_to_remove.empty())
{
LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove);
@@ -6920,6 +6901,47 @@ void handle_selected_texture_info(void*)
}
}
+void handle_selected_material_info()
+{
+ for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+
+ std::string msg;
+ msg.assign("Material info for: \n");
+ msg.append(node->mName);
+
+ U8 te_count = node->getObject()->getNumTEs();
+ // map from material ID to list of faces using it
+ typedef std::map<LLMaterialID, std::vector<U8> > map_t;
+ map_t faces_per_material;
+ for (U8 i = 0; i < te_count; i++)
+ {
+ if (!node->isTESelected(i)) continue;
+
+ const LLMaterialID& material_id = node->getObject()->getTE(i)->getMaterialID();
+ faces_per_material[material_id].push_back(i);
+ }
+ // Per-material, dump which faces are using it.
+ map_t::iterator it;
+ for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it)
+ {
+ const LLMaterialID& material_id = it->first;
+ msg += llformat("%s on face ", material_id.asString().c_str());
+ for (U8 i = 0; i < it->second.size(); ++i)
+ {
+ msg.append( llformat("%d ", (S32)(it->second[i])));
+ }
+ msg.append("\n");
+ }
+
+ LLSD args;
+ args["MESSAGE"] = msg;
+ LLNotificationsUtil::add("SystemMessage", args);
+ }
+}
+
void handle_test_male(void*)
{
LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit");
@@ -7022,6 +7044,15 @@ class LLAdvancedClickRenderShadowOption: public view_listener_t
}
};
+class LLAdvancedClickRenderProfile: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gShaderProfileFrame = TRUE;
+ return true;
+ }
+};
+
void menu_toggle_attached_lights(void* user_data)
{
LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
@@ -8442,11 +8473,10 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");
view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");
view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");
+ commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info));
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
// Develop > Render
- view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas");
- view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas");
view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");
view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
@@ -8460,7 +8490,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");
view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");
view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");
-
+ view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 63de1ab77a..91efed1508 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -201,6 +201,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mTotalCRC(0),
mListIndex(-1),
mTEImages(NULL),
+ mTENormalMaps(NULL),
+ mTESpecularMaps(NULL),
mGLName(0),
mbCanSelect(TRUE),
mFlags(0),
@@ -321,6 +323,18 @@ void LLViewerObject::deleteTEImages()
{
delete[] mTEImages;
mTEImages = NULL;
+
+ if (mTENormalMaps != NULL)
+ {
+ delete[] mTENormalMaps;
+ mTENormalMaps = NULL;
+ }
+
+ if (mTESpecularMaps != NULL)
+ {
+ delete[] mTESpecularMaps;
+ mTESpecularMaps = NULL;
+ }
}
void LLViewerObject::markDead()
@@ -516,6 +530,17 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)
}
}
+void LLViewerObject::setSelected(BOOL sel)
+{
+ mUserSelected = sel;
+ resetRot();
+
+ if (!sel)
+ {
+ setAllTESelected(false);
+ }
+}
+
// This method returns true if the object is over land owned by the
// agent.
bool LLViewerObject::isReturnable()
@@ -3796,19 +3821,19 @@ LLViewerObject* LLViewerObject::getRootEdit() const
}
-BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection,
+ LLVector4a* intersection,
LLVector2* tex_coord,
- LLVector3* normal,
- LLVector3* bi_normal)
+ LLVector4a* normal,
+ LLVector4a* tangent)
{
return false;
}
-BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end)
+BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end)
{
if (mDrawable.isNull() || mDrawable->isDead())
{
@@ -3825,11 +3850,7 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect
size.setSub(ext[1], ext[0]);
size.mul(0.5f);
- LLVector4a starta, enda;
- starta.load3(start.mV);
- enda.load3(end.mV);
-
- return LLLineSegmentBoxIntersect(starta, enda, center, size);
+ return LLLineSegmentBoxIntersect(start, end, center, size);
}
U8 LLViewerObject::getMediaType() const
@@ -3928,25 +3949,39 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
{
LLPointer<LLViewerTexture> *new_images;
new_images = new LLPointer<LLViewerTexture>[num_tes];
+
+ LLPointer<LLViewerTexture> *new_normmaps;
+ new_normmaps = new LLPointer<LLViewerTexture>[num_tes];
+
+ LLPointer<LLViewerTexture> *new_specmaps;
+ new_specmaps = new LLPointer<LLViewerTexture>[num_tes];
for (i = 0; i < num_tes; i++)
{
if (i < getNumTEs())
{
new_images[i] = mTEImages[i];
+ new_normmaps[i] = mTENormalMaps[i];
+ new_specmaps[i] = mTESpecularMaps[i];
}
else if (getNumTEs())
{
new_images[i] = mTEImages[getNumTEs()-1];
+ new_normmaps[i] = mTENormalMaps[getNumTEs()-1];
+ new_specmaps[i] = mTESpecularMaps[getNumTEs()-1];
}
else
{
new_images[i] = NULL;
+ new_normmaps[i] = NULL;
+ new_specmaps[i] = NULL;
}
}
deleteTEImages();
mTEImages = new_images;
+ mTENormalMaps = new_normmaps;
+ mTESpecularMaps = new_specmaps;
}
else
{
@@ -4025,12 +4060,18 @@ void LLViewerObject::sendTEUpdate() const
void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
{
LLPrimitive::setTE(te, texture_entry);
-// This doesn't work, don't get any textures.
-// if (mDrawable.notNull() && mDrawable->isVisible())
-// {
- const LLUUID& image_id = getTE(te)->getID();
+
+ const LLUUID& image_id = getTE(te)->getID();
mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-// }
+
+ if (getTE(te)->getMaterialParams().notNull())
+ {
+ const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
+ mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
+ mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ }
}
void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
@@ -4065,6 +4106,52 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
return retval;
}
+S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image)
+{
+ S32 retval = TEM_CHANGE_TEXTURE;
+ const LLUUID& uuid = image ? image->getID() : LLUUID::null;
+ if (uuid != getTE(te)->getID() ||
+ uuid == LLUUID::null)
+ {
+ LLTextureEntry* tep = getTE(te);
+ LLMaterial* mat = NULL;
+ if (tep)
+ {
+ mat = tep->getMaterialParams();
+ }
+
+ if (mat)
+ {
+ mat->setNormalID(uuid);
+ }
+ }
+ changeTENormalMap(te,image);
+ return retval;
+}
+
+S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image)
+{
+ S32 retval = TEM_CHANGE_TEXTURE;
+ const LLUUID& uuid = image ? image->getID() : LLUUID::null;
+ if (uuid != getTE(te)->getID() ||
+ uuid == LLUUID::null)
+ {
+ LLTextureEntry* tep = getTE(te);
+ LLMaterial* mat = NULL;
+ if (tep)
+ {
+ mat = tep->getMaterialParams();
+ }
+
+ if (mat)
+ {
+ mat->setSpecularID(uuid);
+ }
+ }
+ changeTESpecularMap(te, image);
+ return retval;
+}
+
//virtual
void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
{
@@ -4075,6 +4162,26 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
mTEImages[index] = new_image ;
}
+void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image)
+{
+ if(index < 0 || index >= getNumTEs())
+ {
+ return ;
+ }
+ mTENormalMaps[index] = new_image ;
+ refreshMaterials();
+}
+
+void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image)
+{
+ if(index < 0 || index >= getNumTEs())
+ {
+ return ;
+ }
+ mTESpecularMaps[index] = new_image ;
+ refreshMaterials();
+}
+
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
{
// Invalid host == get from the agent's sim
@@ -4083,6 +4190,19 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
return setTETextureCore(te,image);
}
+S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid)
+{
+ LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
+ return setTENormalMapCore(te, image);
+}
+
+S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid)
+{
+ LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
+ return setTESpecularMapCore(te, image);
+}
S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)
{
@@ -4243,6 +4363,61 @@ S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
return retval;
}
+S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
+{
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS("Material") << "No texture entry for te " << (S32)te
+ << ", object " << mID
+ << ", material " << pMaterialID
+ << LL_ENDL;
+ }
+ //else if (pMaterialID != tep->getMaterialID())
+ {
+ LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te
+ << ", object " << mID
+ << ", material " << pMaterialID
+ << LL_ENDL;
+ retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
+ refreshMaterials();
+ }
+ return retval;
+}
+
+S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
+{
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+ return 0;
+ }
+
+ retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
+ LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
+ << ", object " << mID
+ << " (" << retval << ")"
+ << LL_ENDL;
+ setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
+ setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
+
+ refreshMaterials();
+ return retval;
+}
+
+void LLViewerObject::refreshMaterials()
+{
+ setChanged(ALL_CHANGED);
+ if (mDrawable.notNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
+ dirtySpatialGroup(TRUE);
+ }
+}
S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
{
@@ -4344,6 +4519,50 @@ LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
}
+LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const
+{
+ // llassert(mTEImages);
+
+ if (face < getNumTEs())
+ {
+ LLViewerTexture* image = mTENormalMaps[face];
+ if (image)
+ {
+ return image;
+ }
+ else
+ {
+ return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ }
+
+ llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
+
+ return NULL;
+}
+
+LLViewerTexture *LLViewerObject::getTESpecularMap(const U8 face) const
+{
+ // llassert(mTEImages);
+
+ if (face < getNumTEs())
+ {
+ LLViewerTexture* image = mTESpecularMaps[face];
+ if (image)
+ {
+ return image;
+ }
+ else
+ {
+ return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ }
+
+ llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
+
+ return NULL;
+}
+
void LLViewerObject::fitFaceTexture(const U8 face)
{
llinfos << "fitFaceTexture not implemented" << llendl;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 0390cbc5b0..0b92af4a93 100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -211,7 +211,7 @@ public:
LLViewerRegion* getRegion() const { return mRegionp; }
BOOL isSelected() const { return mUserSelected; }
- virtual void setSelected(BOOL sel) { mUserSelected = sel; resetRot();}
+ virtual void setSelected(BOOL sel);
const LLUUID &getID() const { return mID; }
U32 getLocalID() const { return mLocalID; }
@@ -258,17 +258,17 @@ public:
//detect if given line segment (in agent space) intersects with this viewer object.
//returns TRUE if intersection detected and returns information about intersection
- virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
- virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end);
+ virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end);
virtual const LLVector3d getPositionGlobal() const;
virtual const LLVector3 &getPositionRegion() const;
@@ -301,7 +301,11 @@ public:
/*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
- S32 setTETextureCore(const U8 te, LLViewerTexture *image);
+ /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
+ /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
+ S32 setTETextureCore(const U8 te, LLViewerTexture *image);
+ S32 setTENormalMapCore(const U8 te, LLViewerTexture *image);
+ S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
@@ -318,10 +322,22 @@ public:
/*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright );
/*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);
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
+
+ // Used by Materials update functions to properly kick off rebuilds
+ // of VBs etc when materials updates require changes.
+ //
+ void refreshMaterials();
+
/*virtual*/ BOOL setMaterial(const U8 material);
virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
+ virtual void changeTENormalMap(S32 index, LLViewerTexture* new_image) ;
+ virtual void changeTESpecularMap(S32 index, LLViewerTexture* new_image) ;
LLViewerTexture *getTEImage(const U8 te) const;
+ LLViewerTexture *getTENormalMap(const U8 te) const;
+ LLViewerTexture *getTESpecularMap(const U8 te) const;
void fitFaceTexture(const U8 face);
void sendTEUpdate() const; // Sends packed representation of all texture entry information
@@ -597,6 +613,8 @@ public:
S32 mListIndex;
LLPointer<LLViewerTexture> *mTEImages;
+ LLPointer<LLViewerTexture> *mTENormalMaps;
+ LLPointer<LLViewerTexture> *mTESpecularMaps;
// Selection, picking and rendering variables
U32 mGLName; // GL "name" used by selection code
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 4fb1b7402c..6beaaf0e7b 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -345,7 +345,7 @@ public:
void getNeighboringRegionsStatus( std::vector<S32>& regions );
const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
-
+
public:
struct CompareDistance
{
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index ba9818946c..e24237522a 100755
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -44,6 +44,18 @@
#if LL_DARWIN
#include "OpenGL/OpenGL.h"
+
+// include spec exp clamp to fix older mac rendering artifacts
+//
+#define SINGLE_FP_PERMUTATION(shader) \
+ if (gGLManager.mIsMobileGF) \
+ { \
+ shader.addPermutation("SINGLE_FP_ONLY","1"); \
+ }
+
+
+#else
+#define SINGLE_FP_PERMUTATION(shader)
#endif
#ifdef LL_RELEASE_FOR_DOWNLOAD
@@ -68,7 +80,7 @@ LLGLSLShader gTransformPositionProgram;
LLGLSLShader gTransformTexCoordProgram;
LLGLSLShader gTransformNormalProgram;
LLGLSLShader gTransformColorProgram;
-LLGLSLShader gTransformBinormalProgram;
+LLGLSLShader gTransformTangentProgram;
//utility shaders
LLGLSLShader gOcclusionProgram;
@@ -81,6 +93,8 @@ LLGLSLShader gTwoTextureAddProgram;
LLGLSLShader gOneTextureNoColorProgram;
LLGLSLShader gDebugProgram;
LLGLSLShader gClipProgram;
+LLGLSLShader gDownsampleDepthProgram;
+LLGLSLShader gDownsampleDepthRectProgram;
LLGLSLShader gAlphaMaskProgram;
//object shaders
@@ -143,6 +157,9 @@ LLGLSLShader gUnderWaterProgram;
//interface shaders
LLGLSLShader gHighlightProgram;
+LLGLSLShader gHighlightNormalProgram;
+LLGLSLShader gHighlightSpecularProgram;
+
LLGLSLShader gPathfindingProgram;
LLGLSLShader gPathfindingNoNormalsProgram;
@@ -200,13 +217,20 @@ LLGLSLShader gDeferredEmissiveProgram;
LLGLSLShader gDeferredPostProgram;
LLGLSLShader gDeferredCoFProgram;
LLGLSLShader gDeferredDoFCombineProgram;
+LLGLSLShader gDeferredPostGammaCorrectProgram;
LLGLSLShader gFXAAProgram;
LLGLSLShader gDeferredPostNoDoFProgram;
LLGLSLShader gDeferredWLSkyProgram;
LLGLSLShader gDeferredWLCloudProgram;
LLGLSLShader gDeferredStarProgram;
+LLGLSLShader gDeferredFullbrightShinyProgram;
+LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
+LLGLSLShader gDeferredSkinnedFullbrightProgram;
LLGLSLShader gNormalMapGenProgram;
+// Deferred materials shaders
+LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
+
LLViewerShaderMgr::LLViewerShaderMgr() :
mVertexShaderLevel(SHADER_COUNT, 0),
mMaxAvatarShaderLevel(0)
@@ -271,9 +295,20 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gUnderWaterProgram);
mShaderList.push_back(&gDeferredSunProgram);
mShaderList.push_back(&gDeferredSoftenProgram);
+ mShaderList.push_back(&gDeferredMaterialProgram[1]);
+ mShaderList.push_back(&gDeferredMaterialProgram[5]);
+ mShaderList.push_back(&gDeferredMaterialProgram[9]);
+ mShaderList.push_back(&gDeferredMaterialProgram[13]);
+ mShaderList.push_back(&gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredAlphaProgram);
mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
mShaderList.push_back(&gDeferredFullbrightProgram);
+ mShaderList.push_back(&gDeferredFullbrightShinyProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
mShaderList.push_back(&gDeferredEmissiveProgram);
mShaderList.push_back(&gDeferredAvatarEyesProgram);
mShaderList.push_back(&gDeferredWaterProgram);
@@ -451,6 +486,12 @@ void LLViewerShaderMgr::setShaders()
S32 deferred_class = 0;
S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+ if (!use_transform_feedback)
+ {
+ transform_class = 0;
+ }
+
if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
gSavedSettings.getBOOL("RenderDeferred") &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
@@ -663,6 +704,8 @@ void LLViewerShaderMgr::unloadShaders()
gOcclusionCubeProgram.unload();
gDebugProgram.unload();
gClipProgram.unload();
+ gDownsampleDepthProgram.unload();
+ gDownsampleDepthRectProgram.unload();
gAlphaMaskProgram.unload();
gUIProgram.unload();
gPathfindingProgram.unload();
@@ -740,6 +783,8 @@ void LLViewerShaderMgr::unloadShaders()
gAvatarEyeballProgram.unload();
gAvatarPickProgram.unload();
gHighlightProgram.unload();
+ gHighlightNormalProgram.unload();
+ gHighlightSpecularProgram.unload();
gWLSkyProgram.unload();
gWLCloudProgram.unload();
@@ -760,7 +805,7 @@ void LLViewerShaderMgr::unloadShaders()
gTransformTexCoordProgram.unload();
gTransformNormalProgram.unload();
gTransformColorProgram.unload();
- gTransformBinormalProgram.unload();
+ gTransformTangentProgram.unload();
mVertexShaderLevel[SHADER_LIGHTING] = 0;
mVertexShaderLevel[SHADER_OBJECT] = 0;
@@ -780,9 +825,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// Load basic dependency shaders first
// All of these have to load for any shaders to function
-#if LL_DARWIN // Mac can't currently handle all 8 lights,
- S32 sum_lights_class = 2;
-#else
S32 sum_lights_class = 3;
// class one cards will get the lower sum lights
@@ -793,7 +835,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
{
sum_lights_class = 2;
}
-#endif
// If we have sun and moon only checked, then only sum those lights.
if (gPipeline.getLightingDetail() == 0)
@@ -801,6 +842,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
sum_lights_class = 1;
}
+#if LL_DARWIN
+ // Work around driver crashes on older Macs when using deferred rendering
+ // NORSPEC-59
+ //
+ if (gGLManager.mIsMobileGF)
+ sum_lights_class = 3;
+#endif
+
// Use the feature table to mask out the max light level to use. Also make sure it's at least 1.
S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");
sum_lights_class = llclamp(sum_lights_class, 1, max_light_class);
@@ -826,12 +875,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
}
shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
-
+
+ boost::unordered_map<std::string, std::string> attribs;
+
// 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) == 0)
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)
{
return FALSE;
}
@@ -879,11 +930,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
-
+
for (U32 i = 0; i < shaders.size(); i++)
{
// Note usage of GL_FRAGMENT_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0)
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)
{
return FALSE;
}
@@ -1097,12 +1148,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostProgram.unload();
gDeferredCoFProgram.unload();
gDeferredDoFCombineProgram.unload();
+ gDeferredPostGammaCorrectProgram.unload();
gFXAAProgram.unload();
gDeferredWaterProgram.unload();
gDeferredWLSkyProgram.unload();
gDeferredWLCloudProgram.unload();
gDeferredStarProgram.unload();
+ gDeferredFullbrightShinyProgram.unload();
+ gDeferredSkinnedFullbrightShinyProgram.unload();
+ gDeferredSkinnedFullbrightProgram.unload();
+
gNormalMapGenProgram.unload();
+ for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ gDeferredMaterialProgram[i].unload();
+ }
return TRUE;
}
@@ -1196,10 +1256,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;
gDeferredSkinnedAlphaProgram.mShaderFiles.clear();
- gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-
+ gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
+ gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1");
+ gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);
// Hack to include uniforms for lighting without linking in lighting file
@@ -1216,7 +1279,57 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredBumpProgram.createShader(NULL, NULL);
}
+
+ gDeferredMaterialProgram[1].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[5].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[9].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[13].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ if (success)
+ {
+ gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i);
+
+ 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].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
+ gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
+ gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ bool has_skin = i & 0x10;
+ gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
+
+ SINGLE_FP_PERMUTATION(gDeferredMaterialProgram[i]);
+
+ if (has_skin)
+ {
+ gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
+ }
+
+ success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
+ }
+ }
+
+ gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[5].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[9].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[13].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+
+
+
if (success)
{
gDeferredTreeProgram.mName = "Deferred Tree Shader";
@@ -1254,6 +1367,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ SINGLE_FP_PERMUTATION(gDeferredLightProgram);
+
success = gDeferredLightProgram.createShader(NULL, NULL);
}
@@ -1264,6 +1380,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ SINGLE_FP_PERMUTATION(gDeferredMultiLightProgram);
+
success = gDeferredMultiLightProgram.createShader(NULL, NULL);
}
@@ -1274,6 +1393,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ SINGLE_FP_PERMUTATION(gDeferredSpotLightProgram);
+
success = gDeferredSpotLightProgram.createShader(NULL, NULL);
}
@@ -1284,6 +1406,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ SINGLE_FP_PERMUTATION(gDeferredMultiSpotLightProgram);
+
success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
}
@@ -1310,6 +1435,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB));
gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ SINGLE_FP_PERMUTATION(gDeferredSunProgram);
+
success = gDeferredSunProgram.createShader(NULL, NULL);
}
@@ -1320,6 +1448,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ SINGLE_FP_PERMUTATION(gDeferredBlurLightProgram);
+
success = gDeferredBlurLightProgram.createShader(NULL, NULL);
}
@@ -1346,8 +1477,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mShaderFiles.clear();
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1");
+ gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ SINGLE_FP_PERMUTATION(gDeferredAlphaProgram);
+
success = gDeferredAlphaProgram.createShader(NULL, NULL);
// Hack
@@ -1385,6 +1521,50 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
+ gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredFullbrightShinyProgram.createShader(NULL, &mShinyUniforms);
+ }
+
+ if (success)
+ {
+ gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader";
+ gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true;
+ gDeferredSkinnedFullbrightProgram.mShaderFiles.clear();
+ gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader";
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true;
+ gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear();
+ gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, &mShinyUniforms);
+ }
+
+ if (success)
+ {
gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";
gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;
gDeferredEmissiveProgram.mFeatures.hasGamma = true;
@@ -1420,6 +1600,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ SINGLE_FP_PERMUTATION(gDeferredSoftenProgram);
+
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);
@@ -1435,6 +1617,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
success = gDeferredShadowProgram.createShader(NULL, NULL);
}
@@ -1444,6 +1627,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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));
+ gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
}
@@ -1455,6 +1639,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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));
+ gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
gDeferredShadowAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
}
@@ -1466,6 +1651,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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));
+ gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarShadowProgram.createShader(NULL, &mAvatarUniforms);
}
@@ -1477,6 +1663,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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));
+ gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
gDeferredAttachmentShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);
}
@@ -1515,8 +1702,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
gDeferredAvatarAlphaProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ 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.addPermutation("USE_DIFFUSE_TEX", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms);
@@ -1524,6 +1714,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
}
+
+ if (success)
+ {
+ gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
+ }
if (success)
{
@@ -2306,6 +2506,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true;
gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true;
gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectSimpleProgram.mShaderFiles.clear();
gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2322,6 +2523,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true;
gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true;
gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectFullbrightProgram.mShaderFiles.clear();
gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2372,6 +2574,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true;
gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true;
gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();
gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2388,6 +2591,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true;
gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;
gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true;
gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();
@@ -2425,6 +2629,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;
gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
@@ -2444,6 +2649,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
@@ -2462,6 +2668,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true;
@@ -2602,6 +2809,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gHighlightNormalProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gHighlightSpecularProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gUIProgram.mName = "UI Shader";
gUIProgram.mShaderFiles.clear();
gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2780,6 +3007,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gDownsampleDepthProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gAlphaMaskProgram.mName = "Alpha Mask Shader";
gAlphaMaskProgram.mShaderFiles.clear();
gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2845,7 +3092,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
gTransformTexCoordProgram.unload();
gTransformNormalProgram.unload();
gTransformColorProgram.unload();
- gTransformBinormalProgram.unload();
+ gTransformTangentProgram.unload();
return TRUE;
}
@@ -2908,16 +3155,16 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
if (success)
{
- gTransformBinormalProgram.mName = "Binormal Transform Shader";
- gTransformBinormalProgram.mShaderFiles.clear();
- gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+ gTransformTangentProgram.mName = "Binormal Transform Shader";
+ gTransformTangentProgram.mShaderFiles.clear();
+ gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
const char* varyings[] = {
- "binormal_out",
+ "tangent_out",
};
- success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings);
+ success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);
}
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index e3d28f2f5c..438853cd6f 100755
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -28,6 +28,7 @@
#define LL_VIEWER_SHADER_MGR_H
#include "llshadermgr.h"
+#include "llmaterial.h"
class LLViewerShaderMgr: public LLShaderMgr
{
@@ -216,7 +217,7 @@ extern LLGLSLShader gTransformPositionProgram;
extern LLGLSLShader gTransformTexCoordProgram;
extern LLGLSLShader gTransformNormalProgram;
extern LLGLSLShader gTransformColorProgram;
-extern LLGLSLShader gTransformBinormalProgram;
+extern LLGLSLShader gTransformTangentProgram;
@@ -229,6 +230,8 @@ extern LLGLSLShader gSplatTextureRectProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;
extern LLGLSLShader gDebugProgram;
extern LLGLSLShader gClipProgram;
+extern LLGLSLShader gDownsampleDepthProgram;
+extern LLGLSLShader gDownsampleDepthRectProgram;
//output tex0[tc0] + tex1[tc1]
extern LLGLSLShader gTwoTextureAddProgram;
@@ -300,6 +303,9 @@ extern LLGLSLShader gGlowExtractProgram;
//interface shaders
extern LLGLSLShader gHighlightProgram;
+extern LLGLSLShader gHighlightNormalProgram;
+extern LLGLSLShader gHighlightSpecularProgram;
+
extern LLGLSLShader gPathfindingProgram;
extern LLGLSLShader gPathfindingNoNormalsProgram;
@@ -318,6 +324,7 @@ extern LLGLSLShader gWLCloudProgram;
extern LLGLSLShader gPostColorFilterProgram;
extern LLGLSLShader gPostNightVisionProgram;
+
// Deferred rendering shaders
extern LLGLSLShader gDeferredImpostorProgram;
extern LLGLSLShader gDeferredWaterProgram;
@@ -349,6 +356,7 @@ extern LLGLSLShader gDeferredCoFProgram;
extern LLGLSLShader gDeferredDoFCombineProgram;
extern LLGLSLShader gFXAAProgram;
extern LLGLSLShader gDeferredPostNoDoFProgram;
+extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
extern LLGLSLShader gDeferredAttachmentShadowProgram;
extern LLGLSLShader gDeferredAlphaProgram;
@@ -359,6 +367,12 @@ extern LLGLSLShader gDeferredAvatarAlphaProgram;
extern LLGLSLShader gDeferredWLSkyProgram;
extern LLGLSLShader gDeferredWLCloudProgram;
extern LLGLSLShader gDeferredStarProgram;
+extern LLGLSLShader gDeferredFullbrightShinyProgram;
+extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
+extern LLGLSLShader gDeferredSkinnedFullbrightProgram;
extern LLGLSLShader gNormalMapGenProgram;
+// Deferred materials shaders
+extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
+
#endif
diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp
index f9a725547f..2b3e293229 100755
--- a/indra/newview/llviewerstatsrecorder.cpp
+++ b/indra/newview/llviewerstatsrecorder.cpp
@@ -166,6 +166,7 @@ void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count)
void LLViewerStatsRecorder::writeToLog( F32 interval )
{
+ size_t data_size = 0;
F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime;
S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures;
@@ -187,7 +188,6 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
<< mObjectUpdateFailures << " update failures"
<< llendl;
- U32 data_size;
if (mObjectCacheFile == NULL)
{
mStartTime = LLTimer::getTotalSeconds();
@@ -255,9 +255,9 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
<< "\n";
data_size = data_msg.str().size();
- if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size)
+ if ( data_size != fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ))
{
- llwarns << "failed to write full stats to " << STATS_FILE_NAME << llendl;
+ llwarns << "Unable to write complete column data to " << STATS_FILE_NAME << llendl;
}
clearStats();
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 4c9ca8b1d7..f929492887 100755
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -55,8 +55,6 @@
#include "llappviewer.h"
#include "llface.h"
#include "llviewercamera.h"
-#include "lltextureatlas.h"
-#include "lltextureatlasmanager.h"
#include "lltextureentry.h"
#include "lltexturemanagerbridge.h"
#include "llmediaentry.h"
@@ -73,6 +71,7 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep =
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;
LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ;
LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ;
const std::string sTesterName("TextureTester");
@@ -98,7 +97,6 @@ S32 LLViewerTexture::sMinLargeImageSize = 65536 ; //256 * 256.
S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;
BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;
F32 LLViewerTexture::sCurrentTime = 0.0f ;
-BOOL LLViewerTexture::sUseTextureAtlas = FALSE ;
F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
@@ -277,7 +275,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
}
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
- const std::string& filename,
+ const std::string& filename,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -290,7 +288,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
}
//static
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -397,7 +395,7 @@ void LLViewerTextureManager::init()
LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
LLViewerTexture::initClass() ;
-
+
// Create a texture manager bridge.
gTextureManagerBridgep = new LLViewerTextureManagerBridge;
@@ -425,6 +423,7 @@ void LLViewerTextureManager::cleanup()
LLViewerFetchedTexture::sSmokeImagep = NULL;
LLViewerFetchedTexture::sMissingAssetImagep = NULL;
LLViewerFetchedTexture::sWhiteImagep = NULL;
+ LLViewerFetchedTexture::sFlatNormalImagep = NULL;
LLViewerMediaTexture::cleanUpClass() ;
}
@@ -565,8 +564,7 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
}
}
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
- LLViewerTexture::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ;
-
+
F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);
@@ -632,9 +630,14 @@ void LLViewerTexture::init(bool firstinit)
mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;
mAdditionalDecodePriority = 0.f ;
mParcelMedia = NULL ;
- mNumFaces = 0 ;
+
mNumVolumes = 0;
- mFaceList.clear() ;
+ mFaceList[LLRender::DIFFUSE_MAP].clear() ;
+ mFaceList[LLRender::NORMAL_MAP].clear() ;
+ mFaceList[LLRender::SPECULAR_MAP].clear() ;
+ mNumFaces[LLRender::DIFFUSE_MAP] =
+ mNumFaces[LLRender::NORMAL_MAP] =
+ mNumFaces[LLRender::SPECULAR_MAP] = 0 ;
mVolumeList.clear();
}
@@ -646,7 +649,9 @@ S8 LLViewerTexture::getType() const
void LLViewerTexture::cleanup()
{
- mFaceList.clear() ;
+ mFaceList[LLRender::DIFFUSE_MAP].clear() ;
+ mFaceList[LLRender::NORMAL_MAP].clear() ;
+ mFaceList[LLRender::SPECULAR_MAP].clear() ;
mVolumeList.clear();
}
@@ -762,38 +767,57 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
}
//virtual
-void LLViewerTexture::addFace(LLFace* facep)
+void LLViewerTexture::addFace(U32 ch, LLFace* facep)
{
- if(mNumFaces >= mFaceList.size())
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mNumFaces[ch] >= mFaceList[ch].size())
{
- mFaceList.resize(2 * mNumFaces + 1) ;
+ mFaceList[ch].resize(2 * mNumFaces[ch] + 1) ;
}
- mFaceList[mNumFaces] = facep ;
- facep->setIndexInTex(mNumFaces) ;
- mNumFaces++ ;
+ mFaceList[ch][mNumFaces[ch]] = facep ;
+ facep->setIndexInTex(ch, mNumFaces[ch]) ;
+ mNumFaces[ch]++ ;
mLastFaceListUpdateTimer.reset() ;
}
//virtual
-void LLViewerTexture::removeFace(LLFace* facep)
+void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
{
- if(mNumFaces > 1)
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mNumFaces[ch] > 1)
{
- S32 index = facep->getIndexInTex() ;
- mFaceList[index] = mFaceList[--mNumFaces] ;
- mFaceList[index]->setIndexInTex(index) ;
+ S32 index = facep->getIndexInTex(ch) ;
+ llassert(index < mFaceList[ch].size());
+ llassert(index < mNumFaces[ch]);
+ mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]] ;
+ mFaceList[ch][index]->setIndexInTex(ch, index) ;
}
else
{
- mFaceList.clear() ;
- mNumFaces = 0 ;
+ mFaceList[ch].clear() ;
+ mNumFaces[ch] = 0 ;
}
mLastFaceListUpdateTimer.reset() ;
}
-S32 LLViewerTexture::getNumFaces() const
+S32 LLViewerTexture::getTotalNumFaces() const
{
- return mNumFaces ;
+ S32 ret = 0;
+
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ ret += mNumFaces[i];
+ }
+
+ return ret;
+}
+
+S32 LLViewerTexture::getNumFaces(U32 ch) const
+{
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+ return mNumFaces[ch];
}
@@ -816,6 +840,8 @@ void LLViewerTexture::removeVolume(LLVOVolume* volumep)
if(mNumVolumes > 1)
{
S32 index = volumep->getIndexInTex() ;
+ llassert(index < mVolumeList.size());
+ llassert(index < mNumVolumes);
mVolumeList[index] = mVolumeList[--mNumVolumes] ;
mVolumeList[index]->setIndexInTex(index) ;
}
@@ -837,18 +863,22 @@ void LLViewerTexture::reorganizeFaceList()
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
- if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size())
+ if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
{
- return ;
+ return;
}
- if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
- return ;
+ if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size())
+ {
+ return ;
+ }
+
+ mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end());
}
-
+
mLastFaceListUpdateTimer.reset() ;
- mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());
}
void LLViewerTexture::reorganizeVolumeList()
@@ -1198,7 +1228,7 @@ void LLViewerFetchedTexture::destroyTexture()
{
return ;
}
-
+
//LL_DEBUGS("Avatar") << mID << llendl;
destroyGLTexture() ;
mFullyLoaded = FALSE ;
@@ -1215,9 +1245,14 @@ void LLViewerFetchedTexture::addToCreateTexture()
mGLTexturep->setComponents(mComponents) ;
force_update = true ;
- for(U32 i = 0 ; i < mNumFaces ; i++)
+ for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j)
{
- mFaceList[i]->dirtyTexture() ;
+ llassert(mNumFaces[j] <= mFaceList[j].size());
+
+ for(U32 i = 0 ; i < mNumFaces[j]; i++)
+ {
+ mFaceList[j][i]->dirtyTexture() ;
+ }
}
//discard the cached raw image and the saved raw image
@@ -1361,11 +1396,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
return FALSE;
}
- if(!(res = insertToAtlas()))
- {
- res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
- resetFaceAtlas() ;
- }
+ res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+
setActive() ;
if (!needsToSaveRawImage())
@@ -1654,28 +1686,32 @@ void LLViewerFetchedTexture::updateVirtualSize()
addTextureStats(0.f, FALSE) ;//reset
}
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- LLFace* facep = mFaceList[i] ;
- if( facep )
- {
- LLDrawable* drawable = facep->getDrawable();
- if (drawable)
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+ {
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+
+ for(U32 i = 0 ; i < mNumFaces[ch]; i++)
+ {
+ LLFace* facep = mFaceList[ch][i] ;
+ if( facep )
{
- if(drawable->isRecentlyVisible())
+ LLDrawable* drawable = facep->getDrawable();
+ if (drawable)
{
- if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&
- drawable->getVObj() && drawable->getVObj()->isSelected())
+ if(drawable->isRecentlyVisible())
{
- setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+ if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&
+ drawable->getVObj() && drawable->getVObj()->isSelected())
+ {
+ setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+ }
+ addTextureStats(facep->getVirtualSize()) ;
+ setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
}
- addTextureStats(facep->getVirtualSize()) ;
- setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
}
}
}
}
-
//reset whether or not a face was selected after 10 seconds
const F32 SELECTION_RESET_TIME = 10.f;
@@ -2780,190 +2816,6 @@ F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const
{
return sCurrentTime - mLastReferencedSavedRawImageTime ;
}
-//----------------------------------------------------------------------------------------------
-//atlasing
-//----------------------------------------------------------------------------------------------
-void LLViewerFetchedTexture::resetFaceAtlas()
-{
- //Nothing should be done here.
-}
-
-//invalidate all atlas slots for this image.
-void LLViewerFetchedTexture::invalidateAtlas(BOOL rebuild_geom)
-{
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- LLFace* facep = mFaceList[i] ;
- facep->removeAtlas() ;
- if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup())
- {
- facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY);
- }
- }
-}
-
-BOOL LLViewerFetchedTexture::insertToAtlas()
-{
- if(!LLViewerTexture::sUseTextureAtlas)
- {
- return FALSE ;
- }
- if(getNumFaces() < 1)
- {
- return FALSE ;
- }
- if(mGLTexturep->getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= mGLTexturep->getDiscardLevelInAtlas())
- {
- return FALSE ;
- }
- if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), mGLTexturep->getTexTarget()))
- {
- return FALSE ;
- }
-
- BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image.
- S32 raw_w = mRawImage->getWidth() ;
- S32 raw_h = mRawImage->getHeight() ;
- F32 xscale = 1.0f, yscale = 1.0f ;
- LLPointer<LLTextureAtlasSlot> slot_infop;
- LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer.
- LLSpatialGroup* groupp ;
- LLFace* facep;
-
- //if the atlas slot pointers for some faces are null, process them later.
- ll_face_list_t waiting_list ;
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- {
- facep = mFaceList[i] ;
-
- //face can not use atlas.
- if(!facep->canUseAtlas())
- {
- if(facep->getAtlasInfo())
- {
- facep->removeAtlas() ;
- }
- ret = FALSE ;
- continue ;
- }
-
- //the atlas slot is updated
- slot_infop = facep->getAtlasInfo() ;
- groupp = facep->getDrawable()->getSpatialGroup() ;
-
- if(slot_infop)
- {
- if(slot_infop->getSpatialGroup() != groupp)
- {
- if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot
- {
- facep->setAtlasInfo(cur_slotp) ;
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
- else //do not forget to update slot_infop->getSpatialGroup().
- {
- LLSpatialGroup* gp = slot_infop->getSpatialGroup() ;
- gp->setCurUpdatingTime(gFrameCount) ;
- gp->setCurUpdatingTexture(this) ;
- gp->setCurUpdatingSlot(slot_infop) ;
- }
- }
- else //same group
- {
- if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated
- {
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
- }
- }
- else
- {
- //if the slot is null, wait to process them later.
- waiting_list.push_back(facep) ;
- continue ;
- }
-
- //----------
- //insert to atlas
- if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
- {
-
- //the texture does not qualify to add to atlas, do not bother to try for other faces.
- //invalidateAtlas();
- return FALSE ;
- }
-
- //update texture scale
- slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
- slot_infop->setTexCoordScale(xscale, yscale) ;
- slot_infop->setValid() ;
- slot_infop->setUpdatedTime(gFrameCount) ;
-
- //update spatial group atlas info
- groupp->setCurUpdatingTime(gFrameCount) ;
- groupp->setCurUpdatingTexture(this) ;
- groupp->setCurUpdatingSlot(slot_infop) ;
-
- //make the face to switch to the atlas.
- facep->setAtlasInUse(TRUE) ;
- }
- }
-
- //process the waiting_list
- for(std::vector<LLFace*>::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter)
- {
- facep = (LLFace*)*iter ;
- groupp = facep->getDrawable()->getSpatialGroup() ;
-
- //check if this texture already inserted to atlas for this group
- if((cur_slotp = groupp->getCurUpdatingSlot(this)))
- {
- facep->setAtlasInfo(cur_slotp) ;
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
-
- //need to reserve a slot from atlas
- slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ;
-
- facep->setAtlasInfo(slot_infop) ;
-
- groupp->setCurUpdatingTime(gFrameCount) ;
- groupp->setCurUpdatingTexture(this) ;
- groupp->setCurUpdatingSlot(slot_infop) ;
-
- //slot allocation failed.
- if(!slot_infop || !slot_infop->getAtlas())
- {
- ret = FALSE ;
- facep->setAtlasInUse(FALSE) ;
- continue ;
- }
-
- //insert to atlas
- if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
- {
- //the texture does not qualify to add to atlas, do not bother to try for other faces.
- ret = FALSE ;
- //invalidateAtlas();
- break ;
- }
-
- //update texture scale
- slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
- slot_infop->setTexCoordScale(xscale, yscale) ;
- slot_infop->setValid() ;
- slot_infop->setUpdatedTime(gFrameCount) ;
-
- //make the face to switch to the atlas.
- facep->setAtlasInUse(TRUE) ;
- }
-
- return ret ;
-}
//----------------------------------------------------------------------------------------------
//end of LLViewerFetchedTexture
@@ -3310,11 +3162,14 @@ BOOL LLViewerMediaTexture::findFaces()
LLViewerTexture* tex = gTextureList.findImage(mID) ;
if(tex) //this media is a parcel media for tex.
{
- const ll_face_list_t* face_list = tex->getFaceList() ;
- U32 end = tex->getNumFaces() ;
- for(U32 i = 0 ; i < end ; i++)
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
- mMediaFaceList.push_back((*face_list)[i]) ;
+ const ll_face_list_t* face_list = tex->getFaceList(ch) ;
+ U32 end = tex->getNumFaces(ch) ;
+ for(U32 i = 0 ; i < end ; i++)
+ {
+ mMediaFaceList.push_back((*face_list)[i]) ;
+ }
}
}
@@ -3379,7 +3234,7 @@ void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
return ; //no need to add the face because the media is not in playing.
}
- switchTexture(facep) ;
+ switchTexture(LLRender::DIFFUSE_MAP, facep) ;
}
void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
@@ -3396,19 +3251,19 @@ void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
}
mIsPlaying = FALSE ; //set to remove the media from the face.
- switchTexture(facep) ;
+ switchTexture(LLRender::DIFFUSE_MAP, facep) ;
mIsPlaying = TRUE ; //set the flag back.
- if(getNumFaces() < 1) //no face referencing to this media
+ if(getTotalNumFaces() < 1) //no face referencing to this media
{
stopPlaying() ;
}
}
//virtual
-void LLViewerMediaTexture::addFace(LLFace* facep)
+void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)
{
- LLViewerTexture::addFace(facep) ;
+ LLViewerTexture::addFace(ch, facep) ;
const LLTextureEntry* te = facep->getTextureEntry() ;
if(te && te->getID().notNull())
@@ -3435,9 +3290,9 @@ void LLViewerMediaTexture::addFace(LLFace* facep)
}
//virtual
-void LLViewerMediaTexture::removeFace(LLFace* facep)
+void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
{
- LLViewerTexture::removeFace(facep) ;
+ LLViewerTexture::removeFace(ch, facep) ;
const LLTextureEntry* te = facep->getTextureEntry() ;
if(te && te->getID().notNull())
@@ -3455,24 +3310,35 @@ void LLViewerMediaTexture::removeFace(LLFace* facep)
}
}
- //
- //we have some trouble here: the texture of the face is changed.
- //we need to find the former texture, and remove it from the list to avoid memory leaking.
- if(!mNumFaces)
+ std::vector<const LLTextureEntry*> te_list;
+
+ for (U32 ch = 0; ch < 3; ++ch)
{
- mTextureList.clear() ;
- return ;
+ //
+ //we have some trouble here: the texture of the face is changed.
+ //we need to find the former texture, and remove it from the list to avoid memory leaking.
+
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+
+ for(U32 j = 0 ; j < mNumFaces[ch] ; j++)
+ {
+ te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use.
+ }
}
- S32 end = getNumFaces() ;
- std::vector<const LLTextureEntry*> te_list(end) ;
- S32 i = 0 ;
- for(U32 j = 0 ; j < mNumFaces ; j++)
+
+ if (te_list.empty())
{
- te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use.
+ mTextureList.clear() ;
+ return ;
}
+
+ S32 end = te_list.size();
+
for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
iter != mTextureList.end(); ++iter)
{
+ S32 i = 0;
+
for(i = 0 ; i < end ; i++)
{
if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
@@ -3517,7 +3383,7 @@ void LLViewerMediaTexture::stopPlaying()
mIsPlaying = FALSE ;
}
-void LLViewerMediaTexture::switchTexture(LLFace* facep)
+void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)
{
if(facep)
{
@@ -3533,7 +3399,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)
if(mIsPlaying) //old textures switch to the media texture
{
- facep->switchTexture(this) ;
+ facep->switchTexture(ch, this) ;
}
else //switch to old textures.
{
@@ -3549,7 +3415,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)
{
tex = LLViewerFetchedTexture::sDefaultImagep ;
}
- facep->switchTexture(tex) ;
+ facep->switchTexture(ch, tex) ;
}
}
}
@@ -3588,14 +3454,17 @@ void LLViewerMediaTexture::setPlaying(BOOL playing)
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
{
- switchTexture(*iter) ;
+ switchTexture(LLRender::DIFFUSE_MAP, *iter) ;
}
}
else //stop playing this media
{
- for(U32 i = mNumFaces ; i ; i--)
+ U32 ch = LLRender::DIFFUSE_MAP;
+
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+ for(U32 i = mNumFaces[ch] ; i ; i--)
{
- switchTexture(mFaceList[i - 1]) ; //current face could be removed in this function.
+ switchTexture(ch, mFaceList[ch][i - 1]) ; //current face could be removed in this function.
}
}
return ;
@@ -3617,14 +3486,18 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
if(mIsPlaying) //media is playing
{
- for(U32 i = 0 ; i < mNumFaces ; i++)
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
- LLFace* facep = mFaceList[i] ;
- if(facep->getDrawable()->isRecentlyVisible())
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+ for(U32 i = 0 ; i < mNumFaces[ch] ; i++)
{
- addTextureStats(facep->getVirtualSize()) ;
- }
- }
+ LLFace* facep = mFaceList[ch][i] ;
+ if(facep->getDrawable()->isRecentlyVisible())
+ {
+ addTextureStats(facep->getVirtualSize()) ;
+ }
+ }
+ }
}
else //media is not in playing
{
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index d2af48f528..d9f3548a29 100755
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -119,6 +119,9 @@ void LLViewerTextureList::doPreloadImages()
LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
LLUIImageList* image_list = LLUIImageList::getInstance();
+ // Set the default flat normal map
+ LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP);
+
image_list->initFromFile();
// turn off clamping and bilinear filtering for uv picking images
@@ -324,7 +327,7 @@ void LLViewerTextureList::restoreGL()
///////////////////////////////////////////////////////////////////////////////
-LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,
+LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -376,7 +379,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
}
LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id);
-
+
if (!imagep.isNull())
{
LLViewerFetchedTexture *texture = imagep.get();
@@ -432,7 +435,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
}
-LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
+LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -475,7 +478,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
{
llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl;
}
-
+
}
if (imagep.isNull())
{
@@ -488,7 +491,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
}
//when this function is called, there is no such texture in the gTextureList with image_id.
-LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
+LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index f95cc9e572..d07010e4a1 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -229,13 +229,13 @@ LLFrameTimer gAwayTriggerTimer;
BOOL gShowOverlayTitle = FALSE;
LLViewerObject* gDebugRaycastObject = NULL;
-LLVector3 gDebugRaycastIntersection;
-LLVector2 gDebugRaycastTexCoord;
-LLVector3 gDebugRaycastNormal;
-LLVector3 gDebugRaycastBinormal;
-S32 gDebugRaycastFaceHit;
-LLVector3 gDebugRaycastStart;
-LLVector3 gDebugRaycastEnd;
+LLVector4a gDebugRaycastIntersection;
+LLVector2 gDebugRaycastTexCoord;
+LLVector4a gDebugRaycastNormal;
+LLVector4a gDebugRaycastTangent;
+S32 gDebugRaycastFaceHit;
+LLVector4a gDebugRaycastStart;
+LLVector4a gDebugRaycastEnd;
// HUD display lines in lower right
BOOL gDisplayWindInfo = FALSE;
@@ -2841,7 +2841,7 @@ void LLViewerWindow::updateUI()
&gDebugRaycastIntersection,
&gDebugRaycastTexCoord,
&gDebugRaycastNormal,
- &gDebugRaycastBinormal,
+ &gDebugRaycastTangent,
&gDebugRaycastStart,
&gDebugRaycastEnd);
}
@@ -3739,7 +3739,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans
}
LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
- LLVector3* intersection)
+ LLVector4a* intersection)
{
S32 x = mouse_x;
S32 y = mouse_y;
@@ -3751,14 +3751,17 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep
}
// world coordinates of mouse
+ // VECTORIZE THIS
LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
LLVector3 mouse_world_start = mouse_point_global;
LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
- return LLHUDIcon::lineSegmentIntersectAll(mouse_world_start, mouse_world_end, intersection);
-
+ LLVector4a start, end;
+ start.load3(mouse_world_start.mV);
+ end.load3(mouse_world_end.mV);
+ return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection);
}
LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth,
@@ -3766,12 +3769,12 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
S32 this_face,
BOOL pick_transparent,
S32* face_hit,
- LLVector3 *intersection,
+ LLVector4a *intersection,
LLVector2 *uv,
- LLVector3 *normal,
- LLVector3 *binormal,
- LLVector3* start,
- LLVector3* end)
+ LLVector4a *normal,
+ LLVector4a *tangent,
+ LLVector4a* start,
+ LLVector4a* end)
{
S32 x = mouse_x;
S32 y = mouse_y;
@@ -3806,17 +3809,27 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
if (!LLViewerJoystick::getInstance()->getOverrideCamera())
{ //always set raycast intersection to mouse_world_end unless
//flycam is on (for DoF effect)
- gDebugRaycastIntersection = mouse_world_end;
+ gDebugRaycastIntersection.load3(mouse_world_end.mV);
}
+ LLVector4a mw_start;
+ mw_start.load3(mouse_world_start.mV);
+ LLVector4a mw_end;
+ mw_end.load3(mouse_world_end.mV);
+
+ LLVector4a mh_start;
+ mh_start.load3(mouse_hud_start.mV);
+ LLVector4a mh_end;
+ mh_end.load3(mouse_hud_end.mV);
+
if (start)
{
- *start = mouse_world_start;
+ *start = mw_start;
}
if (end)
{
- *end = mouse_world_end;
+ *end = mw_end;
}
LLViewerObject* found = NULL;
@@ -3825,16 +3838,16 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
{
if (this_object->isHUDAttachment()) // is a HUD object?
{
- if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent,
- face_hit, intersection, uv, normal, binormal))
+ if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent,
+ face_hit, intersection, uv, normal, tangent))
{
found = this_object;
}
}
else // is a world object
{
- if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent,
- face_hit, intersection, uv, normal, binormal))
+ if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent,
+ face_hit, intersection, uv, normal, tangent))
{
found = this_object;
}
@@ -3842,20 +3855,20 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
}
else // check ALL objects
{
- found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent,
- face_hit, intersection, uv, normal, binormal);
+ found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent,
+ face_hit, intersection, uv, normal, tangent);
if (!found) // if not found in HUD, look in world:
{
- found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent,
- face_hit, intersection, uv, normal, binormal);
+ found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent,
+ face_hit, intersection, uv, normal, tangent);
if (found && !pick_transparent)
{
gDebugRaycastIntersection = *intersection;
}
}
}
-
+
return found;
}
@@ -5112,6 +5125,7 @@ LLPickInfo::LLPickInfo()
mXYCoords(-1, -1),
mIntersection(),
mNormal(),
+ mTangent(),
mBinormal(),
mHUDIcon(NULL),
mPickTransparent(FALSE)
@@ -5133,6 +5147,7 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
mSTCoords(-1.f, -1.f),
mXYCoords(-1, -1),
mNormal(),
+ mTangent(),
mBinormal(),
mHUDIcon(NULL),
mPickTransparent(pick_transparent)
@@ -5143,19 +5158,26 @@ void LLPickInfo::fetchResults()
{
S32 face_hit = -1;
- LLVector3 intersection, normal, binormal;
+ LLVector4a intersection, normal;
+ LLVector4a tangent;
+
LLVector2 uv;
LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection);
+ LLVector4a origin;
+ origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
F32 icon_dist = 0.f;
if (hit_icon)
{
- icon_dist = (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec();
+ LLVector4a delta;
+ delta.setSub(intersection, origin);
+ icon_dist = delta.getLength3().getF32();
}
+
LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
NULL, -1, mPickTransparent, &face_hit,
- &intersection, &uv, &normal, &binormal);
+ &intersection, &uv, &normal, &tangent);
mPickPt = mMousePt;
@@ -5165,9 +5187,13 @@ void LLPickInfo::fetchResults()
LLViewerObject* objectp = hit_object;
+
+ LLVector4a delta;
+ delta.setSub(origin, intersection);
+
if (hit_icon &&
(!objectp ||
- icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec()))
+ icon_dist < delta.getLength3().getF32()))
{
// was this name referring to a hud icon?
mHUDIcon = hit_icon;
@@ -5204,11 +5230,16 @@ void LLPickInfo::fetchResults()
{
mPickType = PICK_OBJECT;
}
- mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY);
+
+ LLVector3 v_intersection(intersection.getF32ptr());
+
+ mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY);
mObjectID = objectp->mID;
mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
- mPosGlobal = gAgent.getPosGlobalFromAgent(intersection);
+
+
+ mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection);
if (mWantSurfaceInfo)
{
@@ -5252,7 +5283,16 @@ void LLPickInfo::getSurfaceInfo()
mIntersection = LLVector3(0,0,0);
mNormal = LLVector3(0,0,0);
mBinormal = LLVector3(0,0,0);
+ mTangent = LLVector4(0,0,0,0);
+ LLVector4a tangent;
+ LLVector4a intersection;
+ LLVector4a normal;
+
+ tangent.clear();
+ normal.clear();
+ intersection.clear();
+
LLViewerObject* objectp = getObject();
if (objectp)
@@ -5260,10 +5300,10 @@ void LLPickInfo::getSurfaceInfo()
if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f,
objectp, -1, mPickTransparent,
&mObjectFace,
- &mIntersection,
+ &intersection,
&mSTCoords,
- &mNormal,
- &mBinormal))
+ &normal,
+ &tangent))
{
// if we succeeded with the intersect above, compute the texture coordinates:
@@ -5272,10 +5312,26 @@ void LLPickInfo::getSurfaceInfo()
LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
if (facep)
{
- mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
- }
+ mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal);
+ }
}
+ mIntersection.set(intersection.getF32ptr());
+ mNormal.set(normal.getF32ptr());
+ mTangent.set(tangent.getF32ptr());
+
+ //extrapoloate binormal from normal and tangent
+
+ LLVector4a binormal;
+ binormal.setCross3(normal, tangent);
+ binormal.mul(tangent.getF32ptr()[3]);
+
+ mBinormal.set(binormal.getF32ptr());
+
+ mBinormal.normalize();
+ mNormal.normalize();
+ mTangent.normalize();
+
// and XY coords:
updateXYCoords();
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index b33488fd78..89f6e3bc26 100755
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -115,6 +115,7 @@ public:
LLVector2 mSTCoords;
LLCoordScreen mXYCoords;
LLVector3 mNormal;
+ LLVector4 mTangent;
LLVector3 mBinormal;
BOOL mPickTransparent;
void getSurfaceInfo();
@@ -357,19 +358,19 @@ public:
void pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& pick_info), BOOL pick_transparent = FALSE);
LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent);
LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
- LLVector3* intersection);
+ LLVector4a* intersection);
LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,
LLViewerObject *this_object = NULL,
S32 this_face = -1,
BOOL pick_transparent = FALSE,
S32* face_hit = NULL,
- LLVector3 *intersection = NULL,
+ LLVector4a *intersection = NULL,
LLVector2 *uv = NULL,
- LLVector3 *normal = NULL,
- LLVector3 *binormal = NULL,
- LLVector3* start = NULL,
- LLVector3* end = NULL);
+ LLVector4a *normal = NULL,
+ LLVector4a *tangent = NULL,
+ LLVector4a* start = NULL,
+ LLVector4a* end = NULL);
// Returns a pointer to the last object hit
@@ -499,13 +500,13 @@ extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar awa
extern LLFrameTimer gAwayTriggerTimer; // how long the avatar has been away
extern LLViewerObject* gDebugRaycastObject;
-extern LLVector3 gDebugRaycastIntersection;
+extern LLVector4a gDebugRaycastIntersection;
extern LLVector2 gDebugRaycastTexCoord;
-extern LLVector3 gDebugRaycastNormal;
-extern LLVector3 gDebugRaycastBinormal;
+extern LLVector4a gDebugRaycastNormal;
+extern LLVector4a gDebugRaycastTangent;
extern S32 gDebugRaycastFaceHit;
-extern LLVector3 gDebugRaycastStart;
-extern LLVector3 gDebugRaycastEnd;
+extern LLVector4a gDebugRaycastStart;
+extern LLVector4a gDebugRaycastEnd;
extern BOOL gDisplayCameraPos;
extern BOOL gDisplayWindInfo;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a0a2ce0caf..7909570883 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1393,19 +1393,20 @@ void LLVOAvatar::renderCollisionVolumes()
if (mNameText.notNull())
{
- LLVector3 unused;
- mNameText->lineSegmentIntersect(LLVector3(0,0,0), LLVector3(0,0,1), unused, TRUE);
+ LLVector4a unused;
+
+ mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);
}
}
-BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection,
+ LLVector4a* intersection,
LLVector2* tex_coord,
- LLVector3* normal,
- LLVector3* bi_normal)
+ LLVector4a* normal,
+ LLVector4a* tangent)
{
if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar)
{
@@ -1422,8 +1423,8 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
glh::matrix4f inverse = mat.inverse();
glh::matrix4f norm_mat = inverse.transpose();
- glh::vec3f p1(start.mV);
- glh::vec3f p2(end.mV);
+ glh::vec3f p1(start.getF32ptr());
+ glh::vec3f p2(end.getF32ptr());
inverse.mult_matrix_vec(p1);
inverse.mult_matrix_vec(p2);
@@ -1442,12 +1443,12 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
if (intersection)
{
- *intersection = LLVector3(res_pos.v);
+ intersection->load3(res_pos.v);
}
if (normal)
{
- *normal = LLVector3(res_norm.v);
+ normal->load3(res_norm.v);
}
return TRUE;
@@ -1483,7 +1484,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
- LLVector3 position;
+ LLVector4a position;
if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))
{
if (intersection)
@@ -1497,14 +1498,14 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
return FALSE;
}
-LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end,
+LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection,
+ LLVector4a* intersection,
LLVector2* tex_coord,
- LLVector3* normal,
- LLVector3* bi_normal)
+ LLVector4a* normal,
+ LLVector4a* tangent)
{
if (isSelf() && !gAgent.needsRenderAvatar())
{
@@ -1515,8 +1516,8 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
if (lineSegmentBoundingBox(start, end))
{
- LLVector3 local_end = end;
- LLVector3 local_intersection;
+ LLVector4a local_end = end;
+ LLVector4a local_intersection;
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
@@ -1530,7 +1531,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
{
LLViewerObject* attached_object = (*attachment_iter);
- if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal))
+ if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 8bf31e3cb3..8d047045cb 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -128,15 +128,15 @@ protected:
public:
/*virtual*/ void updateGL();
/*virtual*/ LLVOAvatar* asAvatar();
- virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
+ virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num,
const EObjectUpdateType update_type,
LLDataPacker *dp);
- virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
/*virtual*/ BOOL updateLOD();
- BOOL updateJointLODs();
- void updateLODRiggedAttachments( void );
+ BOOL updateJointLODs();
+ void updateLODRiggedAttachments( void );
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
S32 totalTextureMemForUUIDS(std::set<LLUUID>& ids);
bool allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const;
@@ -162,22 +162,22 @@ public:
/*virtual*/ void updateRegion(LLViewerRegion *regionp);
/*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);
/*virtual*/ void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
- LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end,
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL); // return the surface tangent at the intersection point
+ LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL); // return the surface tangent at the intersection point
//--------------------------------------------------------------------
// LLCharacter interface and related
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 6a25b765cf..cab5c4bc1d 100755
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -764,8 +764,8 @@ void LLVOGrass::updateDrawable(BOOL force_damped)
}
// virtual
-BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
BOOL ret = FALSE;
@@ -776,7 +776,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
return FALSE;
}
- LLVector3 dir = end-start;
+ LLVector4a dir;
+ dir.setSub(end, start);
mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
@@ -844,23 +845,31 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
U32 idx0 = 0,idx1 = 0,idx2 = 0;
- if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE))
+ LLVector4a v0a,v1a,v2a,v3a;
+
+ v0a.load3(v[0].mV);
+ v1a.load3(v[1].mV);
+ v2a.load3(v[2].mV);
+ v3a.load3(v[3].mV);
+
+
+ if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t))
{
hit = TRUE;
idx0 = 0; idx1 = 1; idx2 = 2;
}
- else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE))
+ else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t))
{
hit = TRUE;
idx0 = 1; idx1 = 3; idx2 = 2;
}
- else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE))
+ else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t))
{
normal1 = -normal1;
hit = TRUE;
idx0 = 2; idx1 = 1; idx2 = 0;
}
- else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE))
+ else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t))
{
normal1 = -normal1;
hit = TRUE;
@@ -883,7 +892,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
closest_t = t;
if (intersection != NULL)
{
- *intersection = start+dir*closest_t;
+ dir.mul(closest_t);
+ intersection->setAdd(start, dir);
}
if (tex_coord != NULL)
@@ -893,7 +903,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
if (normal != NULL)
{
- *normal = normal1;
+ normal->load3(normal1.mV);
}
ret = TRUE;
}
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index b9835b8802..122806766d 100755
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -75,14 +75,14 @@ public:
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
/*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
static S32 sMaxGrassSpecies;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index b46c55321c..af55c8f741 100755
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -714,14 +714,7 @@ BOOL LLVoiceClient::isParticipantAvatar(const LLUUID& id)
BOOL LLVoiceClient::isOnlineSIP(const LLUUID& id)
{
- if (mVoiceModule)
- {
- return mVoiceModule->isOnlineSIP(id);
- }
- else
- {
return FALSE;
- }
}
BOOL LLVoiceClient::getIsSpeaking(const LLUUID& id)
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 714dd6a9f2..e17da9cecd 100755
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -199,7 +199,6 @@ public:
//@{
virtual BOOL getVoiceEnabled(const LLUUID& id)=0; // true if we've received data for this avatar
virtual std::string getDisplayName(const LLUUID& id)=0;
- virtual BOOL isOnlineSIP(const LLUUID &id)=0;
virtual BOOL isParticipantAvatar(const LLUUID &id)=0;
virtual BOOL getIsSpeaking(const LLUUID& id)=0;
virtual BOOL getIsModeratorMuted(const LLUUID& id)=0;
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 838845df80..d30fd5677d 100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -188,17 +188,10 @@ class LLVivoxVoiceClientMuteListObserver : public LLMuteListObserver
/* virtual */ void onChange() { LLVivoxVoiceClient::getInstance()->muteListChanged();}
};
-class LLVivoxVoiceClientFriendsObserver : public LLFriendObserver
-{
-public:
- /* virtual */ void changed(U32 mask) { LLVivoxVoiceClient::getInstance()->updateFriends(mask);}
-};
static LLVivoxVoiceClientMuteListObserver mutelist_listener;
static bool sMuteListListener_listening = false;
-static LLVivoxVoiceClientFriendsObserver *friendslist_listener = NULL;
-
///////////////////////////////////////////////////////////////////////////////////////////////
class LLVivoxVoiceClientCapResponder : public LLHTTPClient::Responder
@@ -397,7 +390,6 @@ void LLVivoxVoiceClient::terminate()
void LLVivoxVoiceClient::cleanUp()
{
deleteAllSessions();
- deleteAllBuddies();
deleteAllVoiceFonts();
deleteVoiceFontTemplates();
}
@@ -483,10 +475,10 @@ void LLVivoxVoiceClient::connectorCreate()
std::string savedLogLevel = gSavedSettings.getString("VivoxDebugLevel");
- if(savedLogLevel != "-1")
+ if(savedLogLevel != "-0")
{
LL_DEBUGS("Voice") << "creating connector with logging enabled" << LL_ENDL;
- loglevel = "10";
+ loglevel = "0";
}
stream
@@ -799,9 +791,9 @@ void LLVivoxVoiceClient::stateMachine()
std::string loglevel = gSavedSettings.getString("VivoxDebugLevel");
if(loglevel.empty())
{
- loglevel = "-1"; // turn logging off completely
+ loglevel = "0"; // turn logging off completely
}
-
+ loglevel = "0"; // turn logging off completely
params.args.add("-ll");
params.args.add(loglevel);
params.cwd = gDirUtilp->getAppRODataDir();
@@ -1209,25 +1201,12 @@ void LLVivoxVoiceClient::stateMachine()
setState(stateVoiceFontsReceived);
}
- // request the current set of block rules (we'll need them when updating the friends list)
- accountListBlockRulesSendMessage();
-
- // request the current set of auto-accept rules
- accountListAutoAcceptRulesSendMessage();
-
// Set up the mute list observer if it hasn't been set up already.
if((!sMuteListListener_listening))
{
LLMuteList::getInstance()->addObserver(&mutelist_listener);
sMuteListListener_listening = true;
}
-
- // Set up the friends list observer if it hasn't been set up already.
- if(friendslist_listener == NULL)
- {
- friendslist_listener = new LLVivoxVoiceClientFriendsObserver;
- LLAvatarTracker::instance().addObserver(friendslist_listener);
- }
// Set the initial state of mic mute, local speaker volume, etc.
{
@@ -1298,9 +1277,7 @@ void LLVivoxVoiceClient::stateMachine()
case stateNoChannel:
LL_DEBUGS("Voice") << "State No Channel" << LL_ENDL;
mSpatialJoiningNum = 0;
- // Do this here as well as inside sendPositionalUpdate().
- // Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync.
- sendFriendsListUpdates();
+
if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
{
@@ -1497,7 +1474,6 @@ void LLVivoxVoiceClient::stateMachine()
mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
sendPositionalUpdate();
}
-
mIsInitialized = true;
}
break;
@@ -1655,7 +1631,7 @@ void LLVivoxVoiceClient::stateMachine()
void LLVivoxVoiceClient::closeSocket(void)
{
mSocket.reset();
- mConnected = false;
+ mConnected = false;
mConnectorHandle.clear();
mAccountHandle.clear();
}
@@ -1672,7 +1648,7 @@ void LLVivoxVoiceClient::loginSendMessage()
<< "<AccountName>" << mAccountName << "</AccountName>"
<< "<AccountPassword>" << mAccountPassword << "</AccountPassword>"
<< "<AudioSessionAnswerMode>VerifyAnswer</AudioSessionAnswerMode>"
- << "<EnableBuddiesAndPresence>true</EnableBuddiesAndPresence>"
+ << "<EnableBuddiesAndPresence>false</EnableBuddiesAndPresence>"
<< "<BuddyManagementMode>Application</BuddyManagementMode>"
<< "<ParticipantPropertyFrequency>5</ParticipantPropertyFrequency>"
<< (autoPostCrashDumps?"<AutopostCrashDumps>true</AutopostCrashDumps>":"")
@@ -1708,42 +1684,6 @@ void LLVivoxVoiceClient::logoutSendMessage()
}
}
-void LLVivoxVoiceClient::accountListBlockRulesSendMessage()
-{
- if(!mAccountHandle.empty())
- {
- std::ostringstream stream;
-
- LL_DEBUGS("Voice") << "requesting block rules" << LL_ENDL;
-
- stream
- << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.ListBlockRules.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "</Request>"
- << "\n\n\n";
-
- writeString(stream.str());
- }
-}
-
-void LLVivoxVoiceClient::accountListAutoAcceptRulesSendMessage()
-{
- if(!mAccountHandle.empty())
- {
- std::ostringstream stream;
-
- LL_DEBUGS("Voice") << "requesting auto-accept rules" << LL_ENDL;
-
- stream
- << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.ListAutoAcceptRules.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "</Request>"
- << "\n\n\n";
-
- writeString(stream.str());
- }
-}
-
void LLVivoxVoiceClient::sessionGroupCreateSendMessage()
{
if(!mAccountHandle.empty())
@@ -2575,10 +2515,7 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void)
{
writeString(stream.str());
}
-
- // Friends list updates can be huge, especially on the first voice login of an account with lots of friends.
- // Batching them all together can choke SLVoice, so send them in separate writes.
- sendFriendsListUpdates();
+
}
void LLVivoxVoiceClient::buildSetCaptureDevice(std::ostringstream &stream)
@@ -2676,275 +2613,6 @@ void LLVivoxVoiceClient::buildLocalAudioUpdates(std::ostringstream &stream)
}
-void LLVivoxVoiceClient::checkFriend(const LLUUID& id)
-{
- buddyListEntry *buddy = findBuddy(id);
-
- // Make sure we don't add a name before it's been looked up in the avatar name cache
- LLAvatarName av_name;
- if (LLAvatarNameCache::get(id, &av_name))
- {
- // *NOTE: We feed legacy names to Vivox because we don't know if their service
- // can support a mix of new and old clients with different sorts of names.
- std::string name = av_name.getAccountName();
-
- if (buddy)
- {
- // This buddy is already in both lists (vivox buddies and avatar cache).
- // Trust the avatar cache more for the display name (vivox display name are notoriously wrong)
- buddy->mDisplayName = name;
- }
- else
- {
- // This buddy was not in the vivox list, needs to be added.
- buddy = addBuddy(sipURIFromID(id), name);
- buddy->mUUID = id;
- }
-
- const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id);
- buddy->mCanSeeMeOnline = (relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS));
- // In all the above cases, the buddy is in the SL friends list and tha name has been resolved (which is how we got here).
- buddy->mNameResolved = true;
- buddy->mInSLFriends = true;
- }
- else
- {
- // This name hasn't been looked up yet in the avatar cache. Don't do anything with this buddy list entry until it has.
- if (buddy)
- {
- buddy->mNameResolved = false;
- }
- // Initiate a lookup.
- // The "lookup completed" callback will ensure that the friends list is rechecked after it completes.
- lookupName(id);
- }
-}
-
-void LLVivoxVoiceClient::clearAllLists()
-{
- // FOR TESTING ONLY
-
- // This will send the necessary commands to delete ALL buddies, autoaccept rules, and block rules SLVoice tells us about.
- buddyListMap::iterator buddy_it;
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end();)
- {
- buddyListEntry *buddy = buddy_it->second;
- buddy_it++;
-
- std::ostringstream stream;
-
- if(buddy->mInVivoxBuddies)
- {
- // delete this entry from the vivox buddy list
- buddy->mInVivoxBuddies = false;
- LL_DEBUGS("Voice") << "delete " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddyDelete.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BuddyURI>" << buddy->mURI << "</BuddyURI>"
- << "</Request>\n\n\n";
- }
-
- if(buddy->mHasBlockListEntry)
- {
- // Delete the associated block list entry (so the block list doesn't fill up with junk)
- buddy->mHasBlockListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BlockMask>" << buddy->mURI << "</BlockMask>"
- << "</Request>\n\n\n";
- }
- if(buddy->mHasAutoAcceptListEntry)
- {
- // Delete the associated auto-accept list entry (so the auto-accept list doesn't fill up with junk)
- buddy->mHasAutoAcceptListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>"
- << "</Request>\n\n\n";
- }
-
- writeString(stream.str());
-
- }
-}
-
-void LLVivoxVoiceClient::sendFriendsListUpdates()
-{
- if(mBuddyListMapPopulated && mBlockRulesListReceived && mAutoAcceptRulesListReceived && mFriendsListDirty)
- {
- mFriendsListDirty = false;
-
- if(0)
- {
- // FOR TESTING ONLY -- clear all buddy list, block list, and auto-accept list entries.
- clearAllLists();
- return;
- }
-
- LL_INFOS("Voice") << "Checking vivox buddy list against friends list..." << LL_ENDL;
-
- buddyListMap::iterator buddy_it;
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++)
- {
- // reset the temp flags in the local buddy list
- buddy_it->second->mInSLFriends = false;
- }
-
- // correlate with the friends list
- {
- LLCollectAllBuddies collect;
- LLAvatarTracker::instance().applyFunctor(collect);
- LLCollectAllBuddies::buddy_map_t::const_iterator it = collect.mOnline.begin();
- LLCollectAllBuddies::buddy_map_t::const_iterator end = collect.mOnline.end();
-
- for ( ; it != end; ++it)
- {
- checkFriend(it->second);
- }
- it = collect.mOffline.begin();
- end = collect.mOffline.end();
- for ( ; it != end; ++it)
- {
- checkFriend(it->second);
- }
- }
-
- LL_INFOS("Voice") << "Sending friend list updates..." << LL_ENDL;
-
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end();)
- {
- buddyListEntry *buddy = buddy_it->second;
- buddy_it++;
-
- // Ignore entries that aren't resolved yet.
- if(buddy->mNameResolved)
- {
- std::ostringstream stream;
-
- if(buddy->mInSLFriends && !buddy->mInVivoxBuddies)
- {
- if(mNumberOfAliases > 0)
- {
- // Add (or update) this entry in the vivox buddy list
- buddy->mInVivoxBuddies = true;
- LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;
- stream
- << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddySet.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BuddyURI>" << buddy->mURI << "</BuddyURI>"
- << "<DisplayName>" << buddy->mDisplayName << "</DisplayName>"
- << "<BuddyData></BuddyData>" // Without this, SLVoice doesn't seem to parse the command.
- << "<GroupID>0</GroupID>"
- << "</Request>\n\n\n";
- }
- }
- else if(!buddy->mInSLFriends)
- {
- // This entry no longer exists in your SL friends list. Remove all traces of it from the Vivox buddy list.
- if(buddy->mInVivoxBuddies)
- {
- // delete this entry from the vivox buddy list
- buddy->mInVivoxBuddies = false;
- LL_DEBUGS("Voice") << "delete " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddyDelete.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BuddyURI>" << buddy->mURI << "</BuddyURI>"
- << "</Request>\n\n\n";
- }
-
- if(buddy->mHasBlockListEntry)
- {
- // Delete the associated block list entry, if any
- buddy->mHasBlockListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BlockMask>" << buddy->mURI << "</BlockMask>"
- << "</Request>\n\n\n";
- }
- if(buddy->mHasAutoAcceptListEntry)
- {
- // Delete the associated auto-accept list entry, if any
- buddy->mHasAutoAcceptListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>"
- << "</Request>\n\n\n";
- }
- }
-
- if(buddy->mInSLFriends)
- {
-
- if(buddy->mCanSeeMeOnline)
- {
- // Buddy should not be blocked.
-
- // If this buddy doesn't already have either a block or autoaccept list entry, we'll update their status when we receive a SubscriptionEvent.
-
- // If the buddy has a block list entry, delete it.
- if(buddy->mHasBlockListEntry)
- {
- buddy->mHasBlockListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BlockMask>" << buddy->mURI << "</BlockMask>"
- << "</Request>\n\n\n";
-
-
- // If we just deleted a block list entry, add an auto-accept entry.
- if(!buddy->mHasAutoAcceptListEntry)
- {
- buddy->mHasAutoAcceptListEntry = true;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.CreateAutoAcceptRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>"
- << "<AutoAddAsBuddy>0</AutoAddAsBuddy>"
- << "</Request>\n\n\n";
- }
- }
- }
- else
- {
- // Buddy should be blocked.
-
- // If this buddy doesn't already have either a block or autoaccept list entry, we'll update their status when we receive a SubscriptionEvent.
-
- // If this buddy has an autoaccept entry, delete it
- if(buddy->mHasAutoAcceptListEntry)
- {
- buddy->mHasAutoAcceptListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>"
- << "</Request>\n\n\n";
-
- // If we just deleted an auto-accept entry, add a block list entry.
- if(!buddy->mHasBlockListEntry)
- {
- buddy->mHasBlockListEntry = true;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.CreateBlockRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BlockMask>" << buddy->mURI << "</BlockMask>"
- << "<PresenceOnly>1</PresenceOnly>"
- << "</Request>\n\n\n";
- }
- }
- }
-
- if(!buddy->mInSLFriends && !buddy->mInVivoxBuddies)
- {
- // Delete this entry from the local buddy list. This should NOT invalidate the iterator,
- // since it has already been incremented to the next entry.
- deleteBuddy(buddy->mURI);
- }
-
- }
- writeString(stream.str());
- }
- }
- }
-}
-
/////////////////////////////
// Response/Event handlers
@@ -3718,7 +3386,7 @@ void LLVivoxVoiceClient::participantUpdatedEvent(
voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager
and event is not fired.
- So, we have to call LLSpeakerMgr::update() here.
+ So, we have to call LLSpeakerMgr::update() here.
*/
LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel();
@@ -3750,83 +3418,6 @@ void LLVivoxVoiceClient::participantUpdatedEvent(
}
}
-void LLVivoxVoiceClient::buddyPresenceEvent(
- std::string &uriString,
- std::string &alias,
- std::string &statusString,
- std::string &applicationString)
-{
- buddyListEntry *buddy = findBuddy(uriString);
-
- if(buddy)
- {
- LL_DEBUGS("Voice") << "Presence event for " << buddy->mDisplayName << " status \"" << statusString << "\", application \"" << applicationString << "\""<< LL_ENDL;
- LL_DEBUGS("Voice") << "before: mOnlineSL = " << (buddy->mOnlineSL?"true":"false") << ", mOnlineSLim = " << (buddy->mOnlineSLim?"true":"false") << LL_ENDL;
-
- if(applicationString.empty())
- {
- // This presence event is from a client that doesn't set up the Application string. Do things the old-skool way.
- // NOTE: this will be needed to support people who aren't on the 3010-class SDK yet.
-
- if ( stricmp("Unknown", statusString.c_str())== 0)
- {
- // User went offline with a non-SLim-enabled viewer.
- buddy->mOnlineSL = false;
- }
- else if ( stricmp("Online", statusString.c_str())== 0)
- {
- // User came online with a non-SLim-enabled viewer.
- buddy->mOnlineSL = true;
- }
- else
- {
- // If the user is online through SLim, their status will be "Online-slc", "Away", or something else.
- // NOTE: we should never see this unless someone is running an OLD version of SLim -- the versions that should be in use now all set the application string.
- buddy->mOnlineSLim = true;
- }
- }
- else if(applicationString.find("SecondLifeViewer") != std::string::npos)
- {
- // This presence event is from a viewer that sets the application string
- if ( stricmp("Unknown", statusString.c_str())== 0)
- {
- // Viewer says they're offline
- buddy->mOnlineSL = false;
- }
- else
- {
- // Viewer says they're online
- buddy->mOnlineSL = true;
- }
- }
- else
- {
- // This presence event is from something which is NOT the SL viewer (assume it's SLim).
- if ( stricmp("Unknown", statusString.c_str())== 0)
- {
- // SLim says they're offline
- buddy->mOnlineSLim = false;
- }
- else
- {
- // SLim says they're online
- buddy->mOnlineSLim = true;
- }
- }
-
- LL_DEBUGS("Voice") << "after: mOnlineSL = " << (buddy->mOnlineSL?"true":"false") << ", mOnlineSLim = " << (buddy->mOnlineSLim?"true":"false") << LL_ENDL;
-
- // HACK -- increment the internal change serial number in the LLRelationship (without changing the actual status), so the UI notices the change.
- LLAvatarTracker::instance().setBuddyOnline(buddy->mUUID,LLAvatarTracker::instance().isBuddyOnline(buddy->mUUID));
-
- notifyFriendObservers();
- }
- else
- {
- LL_DEBUGS("Voice") << "Presence for unknown buddy " << uriString << LL_ENDL;
- }
-}
-
void LLVivoxVoiceClient::messageEvent(
std::string &sessionHandle,
std::string &uriString,
@@ -4017,70 +3608,12 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
}
}
-void LLVivoxVoiceClient::subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType)
-{
- buddyListEntry *buddy = findBuddy(buddyURI);
-
- if(!buddy)
- {
- // Couldn't find buddy by URI, try converting the alias...
- if(!alias.empty())
- {
- LLUUID id;
- if(IDFromName(alias, id))
- {
- buddy = findBuddy(id);
- }
- }
- }
-
- if(buddy)
- {
- std::ostringstream stream;
-
- if(buddy->mCanSeeMeOnline)
- {
- // Sending the response will create an auto-accept rule
- buddy->mHasAutoAcceptListEntry = true;
- }
- else
- {
- // Sending the response will create a block rule
- buddy->mHasBlockListEntry = true;
- }
-
- if(buddy->mInSLFriends)
- {
- buddy->mInVivoxBuddies = true;
- }
-
- stream
- << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.SendSubscriptionReply.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BuddyURI>" << buddy->mURI << "</BuddyURI>"
- << "<RuleType>" << (buddy->mCanSeeMeOnline?"Allow":"Hide") << "</RuleType>"
- << "<AutoAccept>"<< (buddy->mInSLFriends?"1":"0")<< "</AutoAccept>"
- << "<SubscriptionHandle>" << subscriptionHandle << "</SubscriptionHandle>"
- << "</Request>"
- << "\n\n\n";
-
- writeString(stream.str());
- }
-}
-
void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)
{
LL_DEBUGS("Voice") << "got energy " << energy << LL_ENDL;
mTuningEnergy = energy;
}
-void LLVivoxVoiceClient::buddyListChanged()
-{
- // This is called after we receive a BuddyAndGroupListChangedEvent.
- mBuddyListMapPopulated = true;
- mFriendsListDirty = true;
-}
-
void LLVivoxVoiceClient::muteListChanged()
{
// The user's mute list has been updated. Go through the current participant list and sync it with the mute list.
@@ -4099,15 +3632,6 @@ void LLVivoxVoiceClient::muteListChanged()
}
}
-void LLVivoxVoiceClient::updateFriends(U32 mask)
-{
- if(mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::POWERS))
- {
- // Just resend the whole friend list to the daemon
- mFriendsListDirty = true;
- }
-}
-
/////////////////////////////
// Managing list of participants
LLVivoxVoiceClient::participantState::participantState(const std::string &uri) :
@@ -4706,34 +4230,6 @@ bool LLVivoxVoiceClient::answerInvite(std::string &sessionHandle)
return false;
}
-BOOL LLVivoxVoiceClient::isOnlineSIP(const LLUUID &id)
-{
- bool result = false;
- buddyListEntry *buddy = findBuddy(id);
- if(buddy)
- {
- result = buddy->mOnlineSLim;
- LL_DEBUGS("Voice") << "Buddy " << buddy->mDisplayName << " is SIP " << (result?"online":"offline") << LL_ENDL;
- }
-
- if(!result)
- {
- // This user isn't on the buddy list or doesn't show online status through the buddy list, but could be a participant in an existing session if they initiated a text IM.
- sessionState *session = findSession(id);
- if(session && !session->mHandle.empty())
- {
- if((session->mTextStreamState != streamStateUnknown) || (session->mMediaStreamState > streamStateIdle))
- {
- LL_DEBUGS("Voice") << "Open session with " << id << " found, returning SIP online state" << LL_ENDL;
- // we have a p2p text session open with this user, so by definition they're online.
- result = true;
- }
- }
- }
-
- return result;
-}
-
bool LLVivoxVoiceClient::isVoiceWorking() const
{
//Added stateSessionTerminated state to avoid problems with call in parcels with disabled voice (EXT-4758)
@@ -4790,7 +4286,7 @@ BOOL LLVivoxVoiceClient::isSessionCallBackPossible(const LLUUID &session_id)
// Currently this will be false only for PSTN P2P calls.
BOOL LLVivoxVoiceClient::isSessionTextIMPossible(const LLUUID &session_id)
{
- bool result = TRUE;
+ bool result = TRUE;
sessionState *session = findSession(session_id);
if(session != NULL)
@@ -5839,224 +5335,6 @@ void LLVivoxVoiceClient::verifySessionState(void)
}
}
-LLVivoxVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) :
- mURI(uri)
-{
- mOnlineSL = false;
- mOnlineSLim = false;
- mCanSeeMeOnline = true;
- mHasBlockListEntry = false;
- mHasAutoAcceptListEntry = false;
- mNameResolved = false;
- mInVivoxBuddies = false;
- mInSLFriends = false;
-}
-
-void LLVivoxVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName)
-{
- buddyListEntry *buddy = addBuddy(uri, displayName);
- buddy->mInVivoxBuddies = true;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::string &uri)
-{
- std::string empty;
- buddyListEntry *buddy = addBuddy(uri, empty);
- if(buddy->mDisplayName.empty())
- {
- buddy->mNameResolved = false;
- }
- return buddy;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::string &uri, const std::string &displayName)
-{
- buddyListEntry *result = NULL;
- buddyListMap::iterator iter = mBuddyListMap.find(uri);
-
- if (iter != mBuddyListMap.end())
- {
- // Found a matching buddy already in the map.
- LL_DEBUGS("Voice") << "adding existing buddy " << uri << LL_ENDL;
- result = iter->second;
- }
-
- if (!result)
- {
- // participant isn't already in one list or the other.
- LL_DEBUGS("Voice") << "adding new buddy " << uri << LL_ENDL;
- result = new buddyListEntry(uri);
- result->mDisplayName = displayName;
-
- if (!IDFromName(uri, result->mUUID))
- {
- LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL;
- }
-
- mBuddyListMap.insert(buddyListMap::value_type(result->mURI, result));
- }
-
- return result;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddy(const std::string &uri)
-{
- buddyListEntry *result = NULL;
- buddyListMap::iterator iter = mBuddyListMap.find(uri);
- if(iter != mBuddyListMap.end())
- {
- result = iter->second;
- }
-
- return result;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddy(const LLUUID &id)
-{
- buddyListEntry *result = NULL;
- buddyListMap::iterator iter;
-
- for(iter = mBuddyListMap.begin(); iter != mBuddyListMap.end(); iter++)
- {
- if(iter->second->mUUID == id)
- {
- result = iter->second;
- break;
- }
- }
-
- return result;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddyByDisplayName(const std::string &name)
-{
- buddyListEntry *result = NULL;
- buddyListMap::iterator iter;
-
- for(iter = mBuddyListMap.begin(); iter != mBuddyListMap.end(); iter++)
- {
- if(iter->second->mDisplayName == name)
- {
- result = iter->second;
- break;
- }
- }
-
- return result;
-}
-
-void LLVivoxVoiceClient::deleteBuddy(const std::string &uri)
-{
- buddyListMap::iterator iter = mBuddyListMap.find(uri);
- if(iter != mBuddyListMap.end())
- {
- LL_DEBUGS("Voice") << "deleting buddy " << uri << LL_ENDL;
- buddyListEntry *buddy = iter->second;
- mBuddyListMap.erase(iter);
- delete buddy;
- }
- else
- {
- LL_DEBUGS("Voice") << "attempt to delete nonexistent buddy " << uri << LL_ENDL;
- }
-
-}
-
-void LLVivoxVoiceClient::deleteAllBuddies(void)
-{
- while(!mBuddyListMap.empty())
- {
- deleteBuddy(mBuddyListMap.begin()->first);
- }
-
- // Don't want to correlate with friends list when we've emptied the buddy list.
- mBuddyListMapPopulated = false;
-
- // Don't want to correlate with friends list when we've reset the block rules.
- mBlockRulesListReceived = false;
- mAutoAcceptRulesListReceived = false;
-}
-
-void LLVivoxVoiceClient::deleteAllBlockRules(void)
-{
- // Clear the block list entry flags from all local buddy list entries
- buddyListMap::iterator buddy_it;
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++)
- {
- buddy_it->second->mHasBlockListEntry = false;
- }
-}
-
-void LLVivoxVoiceClient::deleteAllAutoAcceptRules(void)
-{
- // Clear the auto-accept list entry flags from all local buddy list entries
- buddyListMap::iterator buddy_it;
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++)
- {
- buddy_it->second->mHasAutoAcceptListEntry = false;
- }
-}
-
-void LLVivoxVoiceClient::addBlockRule(const std::string &blockMask, const std::string &presenceOnly)
-{
- buddyListEntry *buddy = NULL;
-
- // blockMask is the SIP URI of a friends list entry
- buddyListMap::iterator iter = mBuddyListMap.find(blockMask);
- if(iter != mBuddyListMap.end())
- {
- LL_DEBUGS("Voice") << "block list entry for " << blockMask << LL_ENDL;
- buddy = iter->second;
- }
-
- if(buddy == NULL)
- {
- LL_DEBUGS("Voice") << "block list entry for unknown buddy " << blockMask << LL_ENDL;
- buddy = addBuddy(blockMask);
- }
-
- if(buddy != NULL)
- {
- buddy->mHasBlockListEntry = true;
- }
-}
-
-void LLVivoxVoiceClient::addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy)
-{
- buddyListEntry *buddy = NULL;
-
- // blockMask is the SIP URI of a friends list entry
- buddyListMap::iterator iter = mBuddyListMap.find(autoAcceptMask);
- if(iter != mBuddyListMap.end())
- {
- LL_DEBUGS("Voice") << "auto-accept list entry for " << autoAcceptMask << LL_ENDL;
- buddy = iter->second;
- }
-
- if(buddy == NULL)
- {
- LL_DEBUGS("Voice") << "auto-accept list entry for unknown buddy " << autoAcceptMask << LL_ENDL;
- buddy = addBuddy(autoAcceptMask);
- }
-
- if(buddy != NULL)
- {
- buddy->mHasAutoAcceptListEntry = true;
- }
-}
-
-void LLVivoxVoiceClient::accountListBlockRulesResponse(int statusCode, const std::string &statusString)
-{
- // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done.
- mBlockRulesListReceived = true;
-}
-
-void LLVivoxVoiceClient::accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString)
-{
- // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done.
- mAutoAcceptRulesListReceived = true;
-}
-
void LLVivoxVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
{
mParticipantObservers.insert(observer);
@@ -6206,11 +5484,6 @@ void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id,
void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name)
{
- // If the avatar whose name just resolved is on our friends list, resync the friends list.
- if(LLAvatarTracker::instance().getBuddyInfo(id) != NULL)
- {
- mFriendsListDirty = true;
- }
// Iterate over all sessions.
for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++)
{
@@ -6823,7 +6096,6 @@ void LLVivoxVoiceClient::updateVoiceMorphingMenu()
}
}
}
-
void LLVivoxVoiceClient::notifyVoiceFontObservers()
{
LL_DEBUGS("Voice") << "Notifying voice effect observers. Lists changed: " << mVoiceFontListDirty << LL_ENDL;
@@ -7213,18 +6485,6 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
{
deviceString.clear();
}
- else if (!stricmp("Buddies", tag))
- {
- LLVivoxVoiceClient::getInstance()->deleteAllBuddies();
- }
- else if (!stricmp("BlockRules", tag))
- {
- LLVivoxVoiceClient::getInstance()->deleteAllBlockRules();
- }
- else if (!stricmp("AutoAcceptRules", tag))
- {
- LLVivoxVoiceClient::getInstance()->deleteAllAutoAcceptRules();
- }
else if (!stricmp("SessionFont", tag))
{
id = 0;
@@ -7259,7 +6519,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
void LLVivoxProtocolParser::EndTag(const char *tag)
{
const std::string& string = textBuffer;
-
+
responseDepth--;
if (ignoringTags)
@@ -7356,24 +6616,10 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
{
LLVivoxVoiceClient::getInstance()->addRenderDevice(deviceString);
}
- else if (!stricmp("Buddy", tag))
- {
- // NOTE : Vivox does *not* give reliable display name for Buddy tags
- // We don't take those very seriously as a result...
- LLVivoxVoiceClient::getInstance()->processBuddyListEntry(uriString, displayNameString);
- }
- else if (!stricmp("BlockRule", tag))
- {
- LLVivoxVoiceClient::getInstance()->addBlockRule(blockMask, presenceOnly);
- }
else if (!stricmp("BlockMask", tag))
blockMask = string;
else if (!stricmp("PresenceOnly", tag))
presenceOnly = string;
- else if (!stricmp("AutoAcceptRule", tag))
- {
- LLVivoxVoiceClient::getInstance()->addAutoAcceptRule(autoAcceptMask, autoAddAsBuddy);
- }
else if (!stricmp("AutoAcceptMask", tag))
autoAcceptMask = string;
else if (!stricmp("AutoAddAsBuddy", tag))
@@ -7605,16 +6851,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
LLVivoxVoiceClient::getInstance()->auxAudioPropertiesEvent(energy);
}
- else if (!stricmp(eventTypeCstr, "BuddyPresenceEvent"))
- {
- LLVivoxVoiceClient::getInstance()->buddyPresenceEvent(uriString, alias, statusString, applicationString);
- }
- else if (!stricmp(eventTypeCstr, "BuddyAndGroupListChangedEvent"))
- {
- // The buddy list was updated during parsing.
- // Need to recheck against the friends list.
- LLVivoxVoiceClient::getInstance()->buddyListChanged();
- }
else if (!stricmp(eventTypeCstr, "BuddyChangedEvent"))
{
/*
@@ -7637,11 +6873,7 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
{
LLVivoxVoiceClient::getInstance()->sessionNotificationEvent(sessionHandle, uriString, notificationType);
}
- else if (!stricmp(eventTypeCstr, "SubscriptionEvent"))
- {
- LLVivoxVoiceClient::getInstance()->subscriptionEvent(uriString, subscriptionHandle, alias, displayNameString, applicationString, subscriptionType);
- }
- else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent"))
+ else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent"))
{
/*
<Event type="SessionUpdatedEvent">
@@ -7704,14 +6936,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
{
LLVivoxVoiceClient::getInstance()->connectorShutdownResponse(statusCode, statusString);
}
- else if (!stricmp(actionCstr, "Account.ListBlockRules.1"))
- {
- LLVivoxVoiceClient::getInstance()->accountListBlockRulesResponse(statusCode, statusString);
- }
- else if (!stricmp(actionCstr, "Account.ListAutoAcceptRules.1"))
- {
- LLVivoxVoiceClient::getInstance()->accountListAutoAcceptRulesResponse(statusCode, statusString);
- }
else if (!stricmp(actionCstr, "Session.Set3DPosition.1"))
{
// We don't need to process these, but they're so spammy we don't want to log them.
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index a6f40eb3e9..e2d1585c15 100755
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -48,7 +48,6 @@ class LLVivoxProtocolParser;
class LLAvatarName;
class LLVivoxVoiceAccountProvisionResponder;
class LLVivoxVoiceClientMuteListObserver;
-class LLVivoxVoiceClientFriendsObserver;
class LLVivoxVoiceClient : public LLSingleton<LLVivoxVoiceClient>,
@@ -181,7 +180,6 @@ public:
//@{
virtual BOOL getVoiceEnabled(const LLUUID& id); // true if we've received data for this avatar
virtual std::string getDisplayName(const LLUUID& id);
- virtual BOOL isOnlineSIP(const LLUUID &id);
virtual BOOL isParticipantAvatar(const LLUUID &id);
virtual BOOL getIsSpeaking(const LLUUID& id);
virtual BOOL getIsModeratorMuted(const LLUUID& id);
@@ -490,14 +488,10 @@ protected:
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 auxAudioPropertiesEvent(F32 energy);
- void buddyPresenceEvent(std::string &uriString, std::string &alias, std::string &statusString, std::string &applicationString);
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);
- void subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType);
- void buddyListChanged();
void muteListChanged();
- void updateFriends(U32 mask);
/////////////////////////////
// Sending updates of current state
@@ -588,24 +582,6 @@ protected:
typedef std::map<std::string, buddyListEntry*> buddyListMap;
- // This should be called when parsing a buddy list entry sent by SLVoice.
- void processBuddyListEntry(const std::string &uri, const std::string &displayName);
-
- buddyListEntry *addBuddy(const std::string &uri);
- buddyListEntry *addBuddy(const std::string &uri, const std::string &displayName);
- buddyListEntry *findBuddy(const std::string &uri);
- buddyListEntry *findBuddy(const LLUUID &id);
- buddyListEntry *findBuddyByDisplayName(const std::string &name);
- void deleteBuddy(const std::string &uri);
- void deleteAllBuddies(void);
-
- void deleteAllBlockRules(void);
- void addBlockRule(const std::string &blockMask, const std::string &presenceOnly);
- void deleteAllAutoAcceptRules(void);
- void addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy);
- void accountListBlockRulesResponse(int statusCode, const std::string &statusString);
- void accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString);
-
/////////////////////////////
// session control messages
@@ -774,8 +750,7 @@ private:
void buildSetCaptureDevice(std::ostringstream &stream);
void buildSetRenderDevice(std::ostringstream &stream);
- void clearAllLists();
- void checkFriend(const LLUUID& id);
+
void sendFriendsListUpdates();
// start a text IM session with the specified user
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 0b34bbb90f..43a5ddba42 100755
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -65,7 +65,9 @@ void LLVOPartGroup::initClass()
//static
void LLVOPartGroup::restoreGL()
{
- sVB = new LLVertexBuffer(VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+
+ //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);
U32 count = LL_MAX_PARTICLE_COUNT;
sVB->allocateBuffer(count*4, count*6, true);
@@ -410,6 +412,7 @@ void LLVOPartGroup::getGeometry(S32 idx,
right.setCross3(at, up);
right.normalize3fast();
+
up.setCross3(right, at);
up.normalize3fast();
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index de15f0ef43..9a5c5831ca 100755
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -97,10 +97,10 @@ public:
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
- if (data_mask & MAP_BINORMAL)
+ if (data_mask & MAP_TANGENT)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
if (data_mask & MAP_TEXCOORD0)
@@ -936,8 +936,8 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
}
}
-BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -946,7 +946,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
return FALSE;
}
- LLVector3 delta = end-start;
+ LLVector4a da;
+ da.setSub(end, start);
+ LLVector3 delta(da.getF32ptr());
LLVector3 pdelta = delta;
pdelta.mV[2] = 0;
@@ -955,7 +957,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
F32 tdelta = 1.f/plength;
- LLVector3 origin = start - mRegionp->getOriginAgent();
+ LLVector3 v_start(start.getF32ptr());
+
+ LLVector3 origin = v_start - mRegionp->getOriginAgent();
if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
{
@@ -1010,12 +1014,12 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
{
sample.mV[2] = mRegionp->getLandHeightRegion(sample);
}
- *intersection = sample + mRegionp->getOriginAgent();
+ intersection->load3((sample + mRegionp->getOriginAgent()).mV);
}
if (normal)
{
- *normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample));
+ normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);
}
return TRUE;
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index a15878368e..7b53219be8 100755
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -79,14 +79,14 @@ public:
void dirtyPatch();
void dirtyGeom();
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
BOOL mDirtiedPatch;
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 145a0380d6..cd12cd9552 100755
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -1085,132 +1085,6 @@ void LLVOTree::calcNumVerts(U32& vert_count, U32& index_count, S32 trunk_LOD, S3
}
}
-U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha)
-{
- U32 ret = 0;
- //
- // Draws a tree by recursing, drawing branches and then a 'leaf' texture.
- // If stop_level = -1, simply draws the whole tree as a billboarded texture
- //
-
- static F32 constant_twist;
- static F32 width = 0;
-
- //F32 length = ((scale == 1.f)? mTrunkLength:mBranchLength);
- //F32 aspect = ((scale == 1.f)? mTrunkAspect:mBranchAspect);
- F32 length = ((trunk_depth || (scale == 1.f))? mTrunkLength:mBranchLength);
- F32 aspect = ((trunk_depth || (scale == 1.f))? mTrunkAspect:mBranchAspect);
-
- constant_twist = 360.f/branches;
-
- if (!LLPipeline::sReflectionRender && stop_level >= 0)
- {
- //
- // Draw the tree using recursion
- //
- if (depth > stop_level)
- {
- {
- llassert(sLODIndexCount[trunk_LOD] > 0);
- width = scale * length * aspect;
- LLMatrix4 scale_mat;
- scale_mat.mMatrix[0][0] = width;
- scale_mat.mMatrix[1][1] = width;
- scale_mat.mMatrix[2][2] = scale*length;
- scale_mat *= matrix;
-
- gGL.loadMatrix((F32*) scale_mat.mMatrix);
- gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_SHORT, indicesp + sLODIndexOffset[trunk_LOD]);
- gPipeline.addTrianglesDrawn(LEAF_INDICES);
- stop_glerror();
- ret += sLODIndexCount[trunk_LOD];
- }
-
- // Recurse to create more branches
- for (S32 i=0; i < (S32)branches; i++)
- {
- LLMatrix4 trans_mat;
- trans_mat.setTranslation(0,0,scale*length);
- trans_mat *= matrix;
-
- LLQuaternion rot =
- LLQuaternion(20.f*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)) *
- LLQuaternion(droop*DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f)) *
- LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f));
-
- LLMatrix4 rot_mat(rot);
- rot_mat *= trans_mat;
-
- ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha);
- }
- // Recurse to continue trunk
- if (trunk_depth)
- {
- LLMatrix4 trans_mat;
- trans_mat.setTranslation(0,0,scale*length);
- trans_mat *= matrix;
-
- LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1));
- rot_mat *= trans_mat; // rotate a bit around Z when ascending
- ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha);
- }
- }
- else
- {
- //
- // Draw leaves as two 90 deg crossed quads with leaf textures
- //
- {
- LLMatrix4 scale_mat;
- scale_mat.mMatrix[0][0] =
- scale_mat.mMatrix[1][1] =
- scale_mat.mMatrix[2][2] = scale*mLeafScale;
-
- scale_mat *= matrix;
-
-
- gGL.loadMatrix((F32*) scale_mat.mMatrix);
- gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp);
- gPipeline.addTrianglesDrawn(LEAF_INDICES);
- stop_glerror();
- ret += LEAF_INDICES;
- }
- }
- }
- else
- {
- //
- // Draw the tree as a single billboard texture
- //
-
- LLMatrix4 scale_mat;
- scale_mat.mMatrix[0][0] =
- scale_mat.mMatrix[1][1] =
- scale_mat.mMatrix[2][2] = mBillboardScale*mBillboardRatio;
-
- scale_mat *= matrix;
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.translatef(0.0, -0.5, 0.0);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.loadMatrix((F32*) scale_mat.mMatrix);
- gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp);
- gPipeline.addTrianglesDrawn(LEAF_INDICES);
- stop_glerror();
- ret += LEAF_INDICES;
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
-
- return ret;
-}
-
void LLVOTree::updateRadius()
{
if (mDrawable.isNull())
@@ -1238,8 +1112,8 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mDrawable->setPositionGroup(pos);
}
-BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -1268,16 +1142,19 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end
LLVector3 pos, norm;
- if (linesegment_tetrahedron(start, end, center, size, quat, pos, norm))
+ LLVector3 start3(start.getF32ptr());
+ LLVector3 end3(end.getF32ptr());
+
+ if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm))
{
if (intersection)
{
- *intersection = pos;
+ intersection->load3(pos.mV);
}
if (normal)
{
- *normal = norm;
+ normal->load3(norm.mV);
}
return TRUE;
}
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 52debc85ab..2ecb0303a1 100755
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -104,19 +104,16 @@ public:
F32 twist,
F32 droop,
F32 branches,
- F32 alpha);
+ F32 alpha);
- U32 drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha);
-
-
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
static S32 sMaxTreeSpecies;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 135c2e1eca..2c9a9704ba 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -36,6 +36,7 @@
#include "lldir.h"
#include "llflexibleobject.h"
#include "llfloatertools.h"
+#include "llmaterialid.h"
#include "llmaterialtable.h"
#include "llprimitive.h"
#include "llvolume.h"
@@ -76,6 +77,7 @@
#include "llviewershadermgr.h"
#include "llvoavatar.h"
#include "llvocache.h"
+#include "llmaterialmgr.h"
const S32 MIN_QUIET_FRAMES_COALESCE = 30;
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
@@ -554,37 +556,9 @@ void LLVOVolume::animateTextures()
tex_mat.setIdentity();
LLVector3 trans ;
- if(facep->isAtlasInUse())
- {
- //
- //if use atlas for animated texture
- //apply the following transform to the animation matrix.
- //
-
- F32 tcoord_xoffset = 0.f ;
- F32 tcoord_yoffset = 0.f ;
- F32 tcoord_xscale = 1.f ;
- F32 tcoord_yscale = 1.f ;
- if(facep->isAtlasInUse())
- {
- const LLVector2* tmp = facep->getTexCoordOffset() ;
- tcoord_xoffset = tmp->mV[0] ;
- tcoord_yoffset = tmp->mV[1] ;
-
- tmp = facep->getTexCoordScale() ;
- tcoord_xscale = tmp->mV[0] ;
- tcoord_yscale = tmp->mV[1] ;
- }
- trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f));
-
- tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f));
- }
- else //non atlas
- {
- trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
- tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
- }
-
+ trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
+ tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
+
LLVector3 scale(scale_s, scale_t, 1.f);
LLQuaternion quat;
quat.setQuat(rot, 0, 0, -1.f);
@@ -918,6 +892,12 @@ LLFace* LLVOVolume::addFace(S32 f)
{
const LLTextureEntry* te = getTE(f);
LLViewerTexture* imagep = getTEImage(f);
+ if (te->getMaterialParams().notNull())
+ {
+ LLViewerTexture* normalp = getTENormalMap(f);
+ LLViewerTexture* specularp = getTESpecularMap(f);
+ return mDrawable->addFace(te, imagep, normalp, specularp);
+ }
return mDrawable->addFace(te, imagep);
}
@@ -1066,7 +1046,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
{ //already cached
break;
}
- volume->genBinormals(i);
+ volume->genTangents(i);
LLFace::cacheFaceInVRAM(face);
}
}
@@ -1415,6 +1395,11 @@ void LLVOVolume::regenFaces()
facep->setTEOffset(i);
facep->setTexture(getTEImage(i));
+ if (facep->getTextureEntry()->getMaterialParams().notNull())
+ {
+ facep->setNormalMap(getTENormalMap(i));
+ facep->setSpecularMap(getTESpecularMap(i));
+ }
facep->setViewerObject(this);
// If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face.
@@ -1876,7 +1861,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
const LLTextureEntry *tep = getTE(te);
if (!tep)
{
- llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+ LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
}
else if (color != tep->getColor())
{
@@ -1988,6 +1973,62 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
return res;
}
+void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te)
+{
+ LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID);
+ if (pVol)
+ {
+ LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL;
+ if (te >= pVol->getNumTEs())
+ return;
+
+ LLTextureEntry* texture_entry = pVol->getTE(te);
+ if (texture_entry && (texture_entry->getMaterialID() == pMaterialID))
+ {
+ pVol->setTEMaterialParams(te, pMaterialParams);
+ }
+ }
+}
+
+S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
+{
+ S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
+ LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res
+ << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
+ << LL_ENDL;
+
+ LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
+ if (res)
+ {
+ LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3));
+
+ setChanged(ALL_CHANGED);
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
+}
+
+S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
+{
+ S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
+ LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
+ << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
+ << LL_ENDL;
+ setChanged(ALL_CHANGED);
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ return TEM_CHANGE_TEXTURE;
+}
+
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
{
S32 res = LLViewerObject::setTEScale(te, s, t);
@@ -3476,7 +3517,12 @@ F32 LLVOVolume::getBinRadius()
}
else if (mDrawable->isStatic())
{
- radius = llmax((S32) mDrawable->getRadius(), 1)*size_factor;
+ F32 szf = size_factor;
+
+ radius = llmax(mDrawable->getRadius(), szf);
+
+ radius = powf(radius, 1.f+szf/radius);
+
radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1];
radius += mDrawable->mDistanceWRTCamera * distance_factor[0];
}
@@ -3573,8 +3619,8 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
}
-BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
if (!mbCanSelect
@@ -3606,23 +3652,25 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
if (volume)
{
- LLVector3 v_start, v_end, v_dir;
-
+ LLVector4a local_start = start;
+ LLVector4a local_end = end;
+
if (transform)
{
- v_start = agentPositionToVolume(start);
- v_end = agentPositionToVolume(end);
- }
- else
- {
- v_start = start;
- v_end = end;
- }
+ LLVector3 v_start(start.getF32ptr());
+ LLVector3 v_end(end.getF32ptr());
- LLVector3 p;
- LLVector3 n;
+ v_start = agentPositionToVolume(v_start);
+ v_end = agentPositionToVolume(v_end);
+
+ local_start.load3(v_start.mV);
+ local_end.load3(v_end.mV);
+ }
+
+ LLVector4a p;
+ LLVector4a n;
LLVector2 tc;
- LLVector3 bn;
+ LLVector4a tn;
if (intersection != NULL)
{
@@ -3639,9 +3687,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
n = *normal;
}
- if (bi_normal != NULL)
+ if (tangent != NULL)
{
- bn = *bi_normal;
+ tn = *tangent;
}
S32 face_hit = -1;
@@ -3667,8 +3715,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
continue;
}
- face_hit = volume->lineSegmentIntersect(v_start, v_end, i,
- &p, &tc, &n, &bn);
+ face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
+ &p, &tc, &n, &tn);
if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)
{
@@ -3677,7 +3725,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
if (face &&
(pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
{
- v_end = p;
+ local_end = p;
if (face_hitp != NULL)
{
*face_hitp = face_hit;
@@ -3687,7 +3735,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
{
if (transform)
{
- *intersection = volumePositionToAgent(p); // must map back to agent space
+ LLVector3 v_p(p.getF32ptr());
+
+ intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space
}
else
{
@@ -3699,27 +3749,36 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
{
if (transform)
{
- *normal = volumeDirectionToAgent(n);
+ LLVector3 v_n(n.getF32ptr());
+ normal->load3(volumeDirectionToAgent(v_n).mV);
}
else
{
*normal = n;
}
-
- (*normal).normVec();
+ (*normal).normalize3fast();
}
- if (bi_normal != NULL)
+ if (tangent != NULL)
{
if (transform)
{
- *bi_normal = volumeDirectionToAgent(bn);
+ LLVector3 v_tn(tn.getF32ptr());
+
+ LLVector4a trans_tangent;
+ trans_tangent.load3(volumeDirectionToAgent(v_tn).mV);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
+ tangent->setSelectWithMask(mask, tn, trans_tangent);
}
else
{
- *bi_normal = bn;
+ *tangent = tn;
}
- (*bi_normal).normVec();
+ (*tangent).normalize3fast();
}
if (tex_coord != NULL)
@@ -3976,6 +4035,11 @@ bool can_batch_texture(LLFace* facep)
return false;
}
+ if (facep->getTextureEntry()->getMaterialParams().notNull())
+ { //materials don't work with texture batching yet
+ return false;
+ }
+
if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA)
{ //can't batch invisiprims
return false;
@@ -3994,7 +4058,11 @@ static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");
void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
{
LLFastTimer t(FTM_REGISTER_FACE);
-
+ if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT))
+ {
+ LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
+ }
+
if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
{
return;
@@ -4007,7 +4075,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
(type == LLRenderPass::PASS_INVISIBLE) ||
- (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT));
+ (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) ||
+ (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) ||
+ (facep->getTextureEntry()->getFullbright());
if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))
{
@@ -4041,16 +4111,39 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
//drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
-
+ U8 shiny = facep->getTextureEntry()->getShiny();
+
LLViewerTexture* tex = facep->getTexture();
U8 index = facep->getTextureIndex();
+
+ LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
+ LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
bool batchable = false;
+ U32 shader_mask = 0xFFFFFFFF; //no shader
+
+ if (mat)
+ {
+ if (type == LLRenderPass::PASS_ALPHA)
+ {
+ shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND);
+ }
+ else
+ {
+ shader_mask = mat->getShaderMask();
+ }
+ }
+
+
if (index < 255 && idx >= 0)
{
- if (index < draw_vec[idx]->mTextureList.size())
+ if (mat || draw_vec[idx]->mMaterial)
+ { //can't batch textures when materials are present (yet)
+ batchable = false;
+ }
+ else if (index < draw_vec[idx]->mTextureList.size())
{
if (draw_vec[idx]->mTextureList[index].isNull())
{
@@ -4076,16 +4169,20 @@ 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 &&
+ draw_vec[idx]->mBump == bump &&
+ (!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
draw_vec[idx]->mTextureMatrix == tex_mat &&
- draw_vec[idx]->mModelMatrix == model_mat)
+ draw_vec[idx]->mModelMatrix == model_mat &&
+ draw_vec[idx]->mShaderMask == shader_mask)
{
draw_vec[idx]->mCount += facep->getIndicesCount();
draw_vec[idx]->mEnd += facep->getGeomCount();
draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
- if (index >= draw_vec[idx]->mTextureList.size())
+ if (index < 255 && index >= draw_vec[idx]->mTextureList.size())
{
draw_vec[idx]->mTextureList.resize(index+1);
draw_vec[idx]->mTextureList[index] = tex;
@@ -4101,12 +4198,66 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U32 offset = facep->getIndicesStart();
U32 count = facep->getIndicesCount();
LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
- facep->getVertexBuffer(), fullbright, bump);
+ facep->getVertexBuffer(), fullbright, bump);
draw_info->mGroup = group;
draw_info->mVSize = facep->getVirtualSize();
draw_vec.push_back(draw_info);
draw_info->mTextureMatrix = tex_mat;
draw_info->mModelMatrix = model_mat;
+
+ draw_info->mBump = bump;
+ draw_info->mShiny = shiny;
+
+ float alpha[4] =
+ {
+ 0.00f,
+ 0.25f,
+ 0.5f,
+ 0.75f
+ };
+ float spec = alpha[shiny & TEM_SHINY_MASK];
+ LLVector4 specColor(spec, spec, spec, spec);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = spec;
+ draw_info->mSpecularMap = NULL;
+ draw_info->mMaterial = mat;
+ draw_info->mShaderMask = shader_mask;
+
+ if (mat)
+ {
+ draw_info->mMaterialID = mat_id;
+
+ // We have a material. Update our draw info accordingly.
+
+ if (!mat->getSpecularID().isNull())
+ {
+ LLVector4 specColor;
+ specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
+ specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
+ specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
+ specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
+ draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
+ }
+
+ draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
+ draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
+ draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
+
+ }
+ else
+ {
+ if (type == LLRenderPass::PASS_GRASS)
+ {
+ draw_info->mAlphaMaskCutoff = 0.5f;
+ }
+ else
+ {
+ draw_info->mAlphaMaskCutoff = 0.33f;
+ }
+ }
+
if (type == LLRenderPass::PASS_ALPHA)
{ //for alpha sorting
facep->setDrawInfo(draw_info);
@@ -4223,6 +4374,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
std::vector<LLFace*> fullbright_faces;
std::vector<LLFace*> bump_faces;
+ std::vector<LLFace*> norm_faces;
+ std::vector<LLFace*> spec_faces;
+ std::vector<LLFace*> normspec_faces;
std::vector<LLFace*> simple_faces;
std::vector<LLFace*> alpha_faces;
@@ -4267,7 +4421,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
if (vobj->isMesh() &&
- (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
+ ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
{
continue;
}
@@ -4387,66 +4541,123 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLViewerTexture* tex = facep->getTexture();
U32 type = gPipeline.getPoolTypeFromTE(te, tex);
- if (type == LLDrawPool::POOL_ALPHA)
+
+ if (te->getGlow())
{
- if (te->getColor().mV[3] > 0.f)
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
- }
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
+ }
+
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ if (mat && LLPipeline::sRenderDeferred)
+ {
+ U8 alpha_mode = mat->getDiffuseAlphaMode();
+
+ bool is_alpha = type == LLDrawPool::POOL_ALPHA &&
+ (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND ||
+ te->getColor().mV[3] < 0.999f);
+
+ if (is_alpha)
+ { //this face needs alpha blending, override alpha mode
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+
+ if (!is_alpha || te->getColor().mV[3] > 0.f) // //only add the face if it will actually be visible
+ {
+ U32 mask = mat->getShaderMask(alpha_mode);
+ pool->addRiggedFace(facep, mask);
}
}
- else if (te->getShiny())
+ else if (mat)
{
- if (te->getFullbright())
+ bool fullbright = te->getFullbright();
+ bool is_alpha = type == LLDrawPool::POOL_ALPHA;
+ U8 mode = mat->getDiffuseAlphaMode();
+ bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+ mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f)
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
+ pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
}
- else
+ else if (is_alpha || (te->getColor().mV[3] < 0.999f))
{
- if (LLPipeline::sRenderDeferred)
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
- }
- else
+ if (te->getColor().mV[3] > 0.f)
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA);
}
}
- }
- else
- {
- if (te->getFullbright())
+ else if (gPipeline.canUseVertexShaders()
+ && LLPipeline::sRenderBump
+ && te->getShiny()
+ && can_be_shiny)
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
+ pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
}
}
-
- if (te->getGlow())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
- }
-
- if (LLPipeline::sRenderDeferred)
+ else
{
- if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
+ if (type == LLDrawPool::POOL_ALPHA)
{
- if (te->getBumpmap())
+ if (te->getColor().mV[3] > 0.f)
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ }
+ }
+ }
+ else if (te->getShiny())
+ {
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ if (LLPipeline::sRenderDeferred)
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ }
+ }
+ }
+ else
+ {
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ }
+ }
+
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
+ {
+ if (te->getBumpmap())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ }
}
}
}
@@ -4556,8 +4767,31 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (gPipeline.canUseWindLightShadersOnObjects()
&& LLPipeline::sRenderBump)
{
- if (te->getBumpmap())
- { //needs normal + binormal
+ if (LLPipeline::sRenderDeferred && 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)
+ normspec_faces.push_back(facep);
+ }
+ else
+ { //has normal map (needs texcoord1 and tangent)
+ norm_faces.push_back(facep);
+ }
+ }
+ else if (mat->getSpecularID().notNull())
+ { //has specular map but no normal map, needs texcoord2
+ spec_faces.push_back(facep);
+ }
+ else
+ { //has neither specular map nor normal map, only needs texcoord0
+ simple_faces.push_back(facep);
+ }
+ }
+ else if (te->getBumpmap())
+ { //needs normal + tangent
bump_faces.push_back(facep);
}
else if (te->getShiny() || !te->getFullbright())
@@ -4573,7 +4807,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
else
{
if (te->getBumpmap() && LLPipeline::sRenderBump)
- { //needs normal + binormal
+ { //needs normal + tangent
bump_faces.push_back(facep);
}
else if ((te->getShiny() && LLPipeline::sRenderBump) ||
@@ -4623,32 +4857,38 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
+ U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT;
+ U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2;
+ U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2;
+
if (emissive)
{ //emissive faces are present, include emissive byte to preserve batching
simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;
alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE;
bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE;
fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE;
+ norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE;
+ normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE;
+ spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;
}
- bool batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
+ BOOL batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
if (batch_textures)
{
- bump_mask |= LLVertexBuffer::MAP_BINORMAL;
- genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE);
- genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE);
- genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE);
- genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE);
+ bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT;
+ simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
+ alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2;
+ fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
}
- else
- {
- genDrawInfo(group, simple_mask, simple_faces);
- genDrawInfo(group, fullbright_mask, fullbright_faces);
- genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE);
- genDrawInfo(group, alpha_mask, alpha_faces, TRUE);
- }
-
+
+ genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, batch_textures, FALSE);
+ genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, batch_textures);
+ genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, batch_textures);
+ genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, FALSE);
+ genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, FALSE, FALSE);
+ genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, FALSE, FALSE);
+ genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, FALSE, FALSE);
if (!LLPipeline::sDelayVBUpdate)
{
@@ -4800,11 +5040,18 @@ struct CompareBatchBreakerModified
{
return lte->getFullbright() < rte->getFullbright();
}
+ else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams())
+ {
+ return lte->getMaterialParams() < rte->getMaterialParams();
+ }
+ else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny()))
+ {
+ return lte->getShiny() < rte->getShiny();
+ }
else
{
return lhs->getTexture() < rhs->getTexture();
}
-
}
};
@@ -4818,7 +5065,7 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
-void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)
+void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
{
LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
@@ -4888,6 +5135,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
//pull off next face
LLFace* facep = *face_iter;
LLViewerTexture* tex = facep->getTexture();
+ LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams();
if (distance_sort)
{
@@ -4933,6 +5181,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
if (!can_batch_texture(facep))
{ //face is bump mapped or has an animated texture matrix -- can't
//batch more than 1 texture at a time
+ facep->setTextureIndex(0);
break;
}
@@ -4983,13 +5232,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
facep->setTextureIndex(cur_tex);
}
}
+ else
+ {
+ facep->setTextureIndex(0);
+ }
tex = texture_list[0];
}
else
{
while (i != faces.end() &&
- (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
+ (LLPipeline::sTextureBindTest ||
+ (distance_sort ||
+ ((*i)->getTexture() == tex &&
+ ((*i)->getTextureEntry()->getMaterialParams() == mat)))))
{
facep = *i;
@@ -5075,8 +5331,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
index_offset += facep->getGeomCount();
indices_index += facep->getIndicesCount();
-
-
+
//append face to appropriate render batch
BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA;
@@ -5096,7 +5351,130 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
- if (is_alpha)
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ 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;
+ }
+
+ bool use_legacy_bump = te->getBumpmap() && (!mat || mat->getNormalID().isNull());
+
+ if (mat && LLPipeline::sRenderDeferred && !hud_group)
+ {
+ bool material_pass = false;
+
+ if (fullbright)
+ {
+ if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ if (te->getColor().mV[3] >= 0.999f)
+ {
+ material_pass = true;
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ }
+ else if (is_alpha)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else
+ {
+ if (mat->getEnvironmentIntensity() > 0 ||
+ te->getShiny() > 0)
+ {
+ material_pass = true;
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ }
+ }
+ }
+ else if (no_materials)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ }
+ else if (te->getColor().mV[3] < 0.999f)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else if (use_legacy_bump)
+ {
+ // we have a material AND legacy bump settings, but no normal map
+ registerFace(group, facep, LLRenderPass::PASS_BUMP);
+ }
+ else
+ {
+ material_pass = true;
+ }
+
+ if (material_pass)
+ {
+ U32 pass[] =
+ {
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA,
+ LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND,
+ LLRenderPass::PASS_SPECMAP_MASK,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND,
+ LLRenderPass::PASS_NORMMAP_MASK,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND,
+ LLRenderPass::PASS_NORMSPEC_MASK,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ };
+
+ U32 mask = mat->getShaderMask();
+
+ llassert(mask < sizeof(pass)/sizeof(U32));
+
+ mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1));
+
+ registerFace(group, facep, pass[mask]);
+ }
+ }
+ else if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+ if (te->getColor().mV[3] < 0.999f)
+ {
+ mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK);
+ }
+ else if (is_alpha || (te->getColor().mV[3] < 0.999f))
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else if (gPipeline.canUseVertexShaders()
+ && LLPipeline::sRenderBump
+ && te->getShiny()
+ && can_be_shiny)
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY);
+ }
+ else
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE);
+ }
+ }
+ else if (is_alpha)
{
// can we safely treat this as an alpha mask?
if (facep->getFaceColor().mV[3] <= 0.f)
@@ -5121,7 +5499,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else if (gPipeline.canUseVertexShaders()
&& LLPipeline::sRenderBump
- && te->getShiny())
+ && te->getShiny()
+ && can_be_shiny)
{ //shiny
if (tex->getPrimaryFormat() == GL_ALPHA)
{ //invisiprim+shiny
@@ -5138,7 +5517,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
}
}
- else if (te->getBumpmap())
+ else if (use_legacy_bump)
{ //register in deferred bump pass
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
@@ -5165,22 +5544,36 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else if (fullbright || bake_sunlight)
{ //fullbright
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
- if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && te->getBumpmap())
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ }
+ if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)
{ //if this is the deferred render and a bump map is present, register in post deferred bump
registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
}
}
else
{
- if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap())
+ if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && use_legacy_bump)
{ //non-shiny or fullbright deferred bump
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
else
{ //all around simple
llassert(mask & LLVertexBuffer::MAP_NORMAL);
- registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ { //material alpha mask can be respected in non-deferred
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ }
}
}
@@ -5200,7 +5593,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
- if (!force_simple && te->getBumpmap() && LLPipeline::sRenderBump)
+ if (!force_simple && LLPipeline::sRenderBump && use_legacy_bump)
{
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
@@ -5289,4 +5682,3 @@ void LLHUDPartition::shift(const LLVector4a &offset)
//HUD objects don't shift with region crossing. That would be silly.
}
-
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 5482c80f2b..7503f8c5aa 100755
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -31,12 +31,14 @@
#include "llviewertexture.h"
#include "llviewermedia.h"
#include "llframetimer.h"
+#include "lllocalbitmaps.h"
#include "m3math.h" // LLMatrix3
#include "m4math.h" // LLMatrix4
#include <map>
class LLViewerTextureAnim;
class LLDrawPool;
+class LLMaterialID;
class LLSelectNode;
class LLObjectMediaDataClient;
class LLObjectMediaNavigateClient;
@@ -135,14 +137,14 @@ public:
/*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const;
/*virtual*/ U32 getHighLODTriangleCount();
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
LLVector3 agentPositionToVolume(const LLVector3& pos) const;
@@ -157,6 +159,7 @@ public:
const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
void markForUpdate(BOOL priority) { LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; }
+ void faceMappingChanged() { mFaceMappingChanged=TRUE; };
/*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
@@ -185,6 +188,11 @@ public:
/*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);
+
+ 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);
@@ -378,3 +386,4 @@ protected:
};
#endif // LL_LLVOVOLUME_H
+
diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp
index b04d30db55..dba3970635 100755
--- a/indra/newview/llwlparamset.cpp
+++ b/indra/newview/llwlparamset.cpp
@@ -33,6 +33,7 @@
#include "llglslshader.h"
#include "lluictrlfactory.h"
#include "llsliderctrl.h"
+#include "pipeline.h"
#include <llgl.h>
@@ -127,6 +128,13 @@ void LLWLParamSet::update(LLGLSLShader * shader) const
}
}
}
+
+ if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender)
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
}
void LLWLParamSet::set(const std::string& paramName, float x)
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index d9da639af9..ebd96702a1 100755
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -274,7 +274,9 @@ void LLWorld::removeRegion(const LLHost &host)
mActiveRegionList.remove(regionp);
mCulledRegionList.remove(regionp);
mVisibleRegionList.remove(regionp);
-
+
+ mRegionRemovedSignal(regionp);
+
delete regionp;
updateWaterObjects();
@@ -402,6 +404,19 @@ LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
return NULL;
}
+LLViewerRegion* LLWorld::getRegionFromID(const LLUUID& region_id)
+{
+ for (region_list_t::iterator iter = mRegionList.begin();
+ iter != mRegionList.end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ if (regionp->getRegionID() == region_id)
+ {
+ return regionp;
+ }
+ }
+ return NULL;
+}
void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
{
@@ -1246,6 +1261,11 @@ bool LLWorld::isRegionListed(const LLViewerRegion* region) const
return it != mRegionList.end();
}
+boost::signals2::connection LLWorld::setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb)
+{
+ return mRegionRemovedSignal.connect(cb);
+}
+
LLHTTPRegistration<LLEstablishAgentCommunication>
gHTTPRegistrationEstablishAgentCommunication(
"/message/EstablishAgentCommunication");
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index f350009d10..d0b001ba44 100755
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -76,6 +76,7 @@ public:
LLViewerRegion* getRegionFromPosGlobal(const LLVector3d &pos);
LLViewerRegion* getRegionFromPosAgent(const LLVector3 &pos);
LLViewerRegion* getRegionFromHandle(const U64 &handle);
+ LLViewerRegion* getRegionFromID(const LLUUID& region_id);
BOOL positionRegionValidGlobal(const LLVector3d& pos); // true if position is in valid region
LLVector3d clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos);
@@ -149,6 +150,9 @@ public:
typedef std::list<LLViewerRegion*> region_list_t;
const region_list_t& getRegionList() const { return mActiveRegionList; }
+ typedef boost::signals2::signal<void(LLViewerRegion*)> region_remove_signal_t;
+ boost::signals2::connection setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb);
+
// Returns lists of avatar IDs and their world-space positions within a given distance of a point.
// All arguments are optional. Given containers will be emptied and then filled.
// Not supplying origin or radius input returns data on all avatars in the known regions.
@@ -168,6 +172,8 @@ private:
region_list_t mVisibleRegionList;
region_list_t mCulledRegionList;
+ region_remove_signal_t mRegionRemovedSignal;
+
// Number of points on edge
static const U32 mWidth;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7eed9acb4b..c25d22bbdf 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -233,6 +233,7 @@ LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");
LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");
LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");
LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
+LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS("Materials");
LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
@@ -262,10 +263,13 @@ std::string gPoolNames[] =
"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",
@@ -275,7 +279,7 @@ std::string gPoolNames[] =
"POOL_ALPHA"
};
-void drawBox(const LLVector3& c, const LLVector3& r);
+void drawBox(const LLVector4a& c, const LLVector4a& r);
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v);
LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
@@ -352,6 +356,7 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE;
BOOL LLPipeline::sRenderSoundBeacons = FALSE;
BOOL LLPipeline::sRenderBeacons = FALSE;
BOOL LLPipeline::sRenderHighlight = TRUE;
+LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP;
BOOL LLPipeline::sForceOldBakedUpload = FALSE;
S32 LLPipeline::sUseOcclusion = 0;
BOOL LLPipeline::sDelayVBUpdate = TRUE;
@@ -377,6 +382,7 @@ BOOL LLPipeline::sRenderDeferred = FALSE;
BOOL LLPipeline::sMemAllocationThrottled = FALSE;
S32 LLPipeline::sVisibleLightCount = 0;
F32 LLPipeline::sMinRenderSize = 0.f;
+BOOL LLPipeline::sRenderingHUDs;
// EventHost API LLPipeline listener.
static LLPipelineListener sPipelineListener;
@@ -398,8 +404,8 @@ void validate_framebuffer_object();
bool addDeferredAttachments(LLRenderTarget& target)
{
- return target.addColorAttachment(GL_RGBA) && //specular
- target.addColorAttachment(GL_RGBA); //normal+z
+ return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular
+ target.addColorAttachment(GL_RGB10_A2); //normal+z
}
LLPipeline::LLPipeline() :
@@ -435,10 +441,14 @@ LLPipeline::LLPipeline() :
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),
@@ -485,10 +495,13 @@ void LLPipeline::init()
//create render pass pools
getPool(LLDrawPool::POOL_ALPHA);
getPool(LLDrawPool::POOL_SIMPLE);
+ getPool(LLDrawPool::POOL_ALPHA_MASK);
+ getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
getPool(LLDrawPool::POOL_GRASS);
getPool(LLDrawPool::POOL_FULLBRIGHT);
getPool(LLDrawPool::POOL_INVISIBLE);
getPool(LLDrawPool::POOL_BUMP);
+ getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
@@ -916,12 +929,26 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
S32 shadow_detail = RenderShadowDetail;
BOOL ssao = RenderDeferredSSAO;
+ const U32 occlusion_divisor = 3;
+
//allocate deferred rendering color buffers
- if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ 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 (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+
+ GLuint screenFormat = GL_RGBA16;
+ if (gGLManager.mIsATI)
+ {
+ 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 (samples > 0)
{
if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
@@ -948,6 +975,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 4; i++)
{
if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
+ if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
}
}
else
@@ -955,6 +983,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 4; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -967,6 +996,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 4; i < 6; i++)
{
if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false;
+ if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE)) return false;
}
}
else
@@ -974,6 +1004,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 4; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -990,11 +1021,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
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();
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
@@ -1012,11 +1045,18 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
//static
+void LLPipeline::updateRenderBump()
+{
+ sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+}
+
+//static
void LLPipeline::updateRenderDeferred()
{
BOOL deferred = ((RenderDeferred &&
LLRenderTarget::sUseFBO &&
- LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ LLPipeline::sRenderBump &&
VertexShaderEnable &&
RenderAvatarVP &&
WindLightUseAtmosShaders) ? TRUE : FALSE) &&
@@ -1159,7 +1199,7 @@ void LLPipeline::releaseLUTBuffers()
{
if (mLightFunc)
{
- LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc);
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 0, 1, &mLightFunc);
mLightFunc = 0;
}
}
@@ -1213,7 +1253,7 @@ void LLPipeline::createGLBuffers()
for (U32 i = 0; i < 3; i++)
{
- mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
+ mGlow[i].allocate(512,glow_res, GL_RGBA,FALSE,FALSE);
}
allocateScreenBuffer(resX,resY);
@@ -1264,13 +1304,18 @@ void LLPipeline::createGLBuffers()
gBumpImageList.restoreGL();
}
+F32 lerpf(F32 a, F32 b, F32 w)
+{
+ return a + w * (b - a);
+}
+
void LLPipeline::createLUTBuffers()
{
if (sRenderDeferred)
{
if (!mLightFunc)
{
- U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ /*U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
U8* ls = new U8[lightResX*lightResY];
F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
@@ -1306,13 +1351,62 @@ void LLPipeline::createLUTBuffers()
// Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
}
+ }*/
+
+
+ U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
+ F32* ls = new F32[lightResX*lightResY];
+ //F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions.
+ // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
+ for (U32 y = 0; y < lightResY; ++y)
+ {
+ for (U32 x = 0; x < lightResX; ++x)
+ {
+ ls[y*lightResX+x] = 0;
+ F32 sa = (F32) x/(lightResX-1);
+ F32 spec = (F32) y/(lightResY-1);
+ F32 n = spec * spec * 368;
+
+ // Nothing special here. Just your typical blinn-phong term.
+ spec = powf(sa, n);
+
+ // Apply our normalization function.
+ // Note: This is the full equation that applies the full normalization curve, not an approximation.
+ // This is fine, given we only need to create our LUT once per buffer initialization.
+ spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+
+ // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
+ // Though some older drivers may not like this, newer drivers shouldn't have this problem.
+ ls[y*lightResX+x] = spec;
+
+
+ //beckmann distribution
+ /*F32 alpha = acosf((F32) x/(lightResX-1));
+ F32 m = 1.f - (F32) y/(lightResY-1);
+
+ F32 cos4_alpha = cosf(alpha);
+ cos4_alpha *= cos4_alpha;
+ cos4_alpha *= cos4_alpha;
+
+ F32 tan_alpha = tanf(alpha);
+ F32 tan2_alpha = tan_alpha*tan_alpha;
+
+ F32 k = expf(-(tan2_alpha)/(m*m)) /
+ (3.14159f*m*m*cos4_alpha);
+
+ ls[y*lightResX+x] = k;*/
+ }
}
- LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
+ //LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
delete [] ls;
}
@@ -1516,6 +1610,14 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mGrassPool;
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ poolp = mAlphaMaskPool;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ poolp = mFullbrightAlphaMaskPool;
+ break;
+
case LLDrawPool::POOL_FULLBRIGHT:
poolp = mFullbrightPool;
break;
@@ -1539,7 +1641,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_BUMP:
poolp = mBumpPool;
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ poolp = mMaterialsPool;
+ break;
case LLDrawPool::POOL_ALPHA:
poolp = mAlphaPool;
break;
@@ -1603,20 +1707,44 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
return 0;
}
- bool alpha = te->getColor().mV[3] < 0.999f;
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ bool color_alpha = te->getColor().mV[3] < 0.999f;
+ bool alpha = color_alpha;
if (imagep)
{
alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
}
-
+
+ if (alpha && mat)
+ {
+ switch (mat->getDiffuseAlphaMode())
+ {
+ case 1:
+ alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
+ break;
+ case 0: //alpha mode set to none, never go to alpha pool
+ case 3: //alpha mode set to emissive, never go to alpha pool
+ alpha = color_alpha;
+ break;
+ default: //alpha mode set to "mask", go to alpha pool if fullbright
+ alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool.
+ break;
+ }
+ }
+
if (alpha)
{
return LLDrawPool::POOL_ALPHA;
}
- else if ((te->getBumpmap() || te->getShiny()))
+ else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))
{
return LLDrawPool::POOL_BUMP;
}
+ else if (mat && !alpha)
+ {
+ return LLDrawPool::POOL_MATERIALS;
+ }
else
{
return LLDrawPool::POOL_SIMPLE;
@@ -2312,7 +2440,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- mScreen.bindTarget();
+ if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ {
+ mOcclusionDepth.bindTarget();
+ }
+ else
+ {
+ mScreen.bindTarget();
+ }
}
if (sUseOcclusion > 1)
@@ -2450,7 +2585,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- mScreen.flush();
+ if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ {
+ mOcclusionDepth.flush();
+ }
+ else
+ {
+ mScreen.flush();
+ }
}
}
@@ -2518,6 +2660,73 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
}
}
+void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ LLGLSLShader* shader = NULL;
+
+ if (scratch_space)
+ {
+ scratch_space->copyContents(source,
+ 0, 0, source.getWidth(), source.getHeight(),
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ dest.bindTarget();
+ dest.clear(GL_DEPTH_BUFFER_BIT);
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+ LLStrider<LLVector2> tc0;
+
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE)
+ {
+ shader = &gDownsampleDepthRectProgram;
+ shader->bind();
+ shader->uniform2f("delta", 1.f, 1.f);
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight());
+ }
+ else
+ {
+ shader = &gDownsampleDepthProgram;
+ shader->bind();
+ shader->uniform2f("delta", 1.f/source.getWidth(), 1.f/source.getHeight());
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
+ }
+
+ gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE);
+
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ dest.flush();
+
+ if (last_shader)
+ {
+ last_shader->bind();
+ }
+ else
+ {
+ shader->unbind();
+ }
+}
+
+void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ downsampleDepthBuffer(source, dest, scratch_space);
+ dest.bindTarget();
+ doOcclusion(camera);
+ dest.flush();
+}
+
void LLPipeline::doOcclusion(LLCamera& camera)
{
if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups())
@@ -3579,8 +3788,8 @@ void LLPipeline::postSort(LLCamera& camera)
for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
LLSpatialGroup* group = *i;
- if (sUseOcclusion &&
- group->isOcclusionState(LLSpatialGroup::OCCLUDED) ||
+ if ((sUseOcclusion &&
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||
(RenderAutoHideSurfaceAreaLimit > 0.f &&
group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))
{
@@ -3746,7 +3955,9 @@ void LLPipeline::postSort(LLCamera& camera)
if (!sShadowRender)
{
mSelectedFaces.clear();
-
+
+ LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel());
+
// Draw face highlights for selected faces.
if (LLSelectMgr::getInstance()->getTEMode())
{
@@ -3969,13 +4180,14 @@ void LLPipeline::renderHighlights()
gGL.diffuseColor4f(1,1,1,0.5f);
}
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
+ {
+ mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
{
// Make sure the selection image gets downloaded and decoded
- if (!mFaceSelectImagep)
- {
- mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
- }
mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
U32 count = mSelectedFaces.size();
@@ -3991,7 +4203,7 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
}
-
+
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
{
// Paint 'em red!
@@ -4013,6 +4225,67 @@ void LLPipeline::renderHighlights()
{
gHighlightProgram.unbind();
}
+
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
+ {
+ color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ llerrs << "Bad face on selection" << llendl;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.unbind();
+ }
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
+ {
+ color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ llerrs << "Bad face on selection" << llendl;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.unbind();
+ }
+ }
}
//debug use
@@ -4366,7 +4639,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
}
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
{
LLFastTimer t(FTM_POST_DEFERRED_POOLS);
U32 cur_type = 0;
@@ -4381,7 +4654,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
pool_set_t::iterator iter1 = mPools.begin();
- BOOL occlude = LLPipeline::sUseOcclusion > 1;
+ BOOL occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
while ( iter1 != mPools.end() )
{
@@ -4395,7 +4668,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
LLGLSLShader::bindNoShader();
- doOcclusion(camera);
+ doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
gGL.setColorMask(true, false);
}
@@ -4613,6 +4886,7 @@ void LLPipeline::renderPhysicsDisplay()
mPhysicsDisplay.flush();
}
+extern std::set<LLSpatialGroup*> visible_selected_groups;
void LLPipeline::renderDebug()
{
@@ -5002,8 +5276,8 @@ void LLPipeline::renderDebug()
LLSpatialPartition* part = region->getSpatialPartition(i);
if (part)
{
- if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) ||
- !hud_only && hasRenderType(part->mDrawableType) )
+ if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) ||
+ (!hud_only && hasRenderType(part->mDrawableType)) )
{
part->renderDebug();
}
@@ -5023,6 +5297,27 @@ void LLPipeline::renderDebug()
}
}
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction)
+ { //render visible selected group occlusion geometry
+ gDebugProgram.bind();
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ gGL.diffuseColor3f(1,0,1);
+ for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+
+ LLVector4a fudge;
+ fudge.splat(0.25f); //SG_OCCLUSION_FUDGE
+
+ LLVector4a size;
+ size.setAdd(fudge, group->mBounds[1]);
+
+ drawBox(group->mBounds[0], size);
+ }
+ }
+
+ visible_selected_groups.clear();
+
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.bind();
@@ -5318,6 +5613,32 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ if (mAlphaMaskPool)
+ {
+ llassert(0);
+ llwarns << "Ignoring duplicate alpha mask pool." << llendl;
+ break;
+ }
+ else
+ {
+ mAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ if (mFullbrightAlphaMaskPool)
+ {
+ llassert(0);
+ llwarns << "Ignoring duplicate alpha mask pool." << llendl;
+ break;
+ }
+ else
+ {
+ mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
case LLDrawPool::POOL_GRASS:
if (mGrassPool)
{
@@ -5385,7 +5706,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
mBumpPool = new_poolp;
}
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ if (mMaterialsPool)
+ {
+ llassert(0);
+ llwarns << "Ignorning duplicate materials pool." << llendl;
+ }
+ else
+ {
+ mMaterialsPool = new_poolp;
+ }
+ break;
case LLDrawPool::POOL_ALPHA:
if( mAlphaPool )
{
@@ -5394,7 +5725,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
else
{
- mAlphaPool = new_poolp;
+ mAlphaPool = (LLDrawPoolAlpha*) new_poolp;
}
break;
@@ -5474,6 +5805,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mSimplePool = NULL;
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ llassert(mAlphaMaskPool == poolp);
+ mAlphaMaskPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ llassert(mFullbrightAlphaMaskPool == poolp);
+ mFullbrightAlphaMaskPool = NULL;
+ break;
+
case LLDrawPool::POOL_GRASS:
llassert(mGrassPool == poolp);
mGrassPool = NULL;
@@ -5525,7 +5866,12 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
llassert( poolp == mBumpPool );
mBumpPool = NULL;
break;
-
+
+ case LLDrawPool::POOL_MATERIALS:
+ llassert(poolp == mMaterialsPool);
+ mMaterialsPool = NULL;
+ break;
+
case LLDrawPool::POOL_ALPHA:
llassert( poolp == mAlphaPool );
mAlphaPool = NULL;
@@ -5588,8 +5934,15 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
LLLightState* light = gGL.getLight(1);
- mHWLightColors[1] = diffuse;
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*diffuse.mV[0] = powf(diffuse.mV[0], 2.2f);
+ diffuse.mV[1] = powf(diffuse.mV[1], 2.2f);
+ diffuse.mV[2] = powf(diffuse.mV[2], 2.2f);*/
+ }
+ mHWLightColors[1] = diffuse;
+
light->setDiffuse(diffuse);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
@@ -5628,6 +5981,13 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
}
backlight_diffuse *= backlight_mag / max_component;
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f);
+ backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f);
+ backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[1] = backlight_diffuse;
LLLightState* light = gGL.getLight(1);
@@ -5834,6 +6194,14 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
LLVector4 light_pos(mSunDir, 0.0f);
LLColor4 light_diffuse = mSunDiffuse;
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f);
+ light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f);
+ light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[0] = light_diffuse;
LLLightState* light = gGL.getLight(0);
@@ -5902,6 +6270,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic? probably trying to match a historic behavior.
float linatten = x / (light_radius); // % of brightness at radius
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_color.mV[0] = powf(light_color.mV[0], 2.2f);
+ light_color.mV[1] = powf(light_color.mV[1], 2.2f);
+ light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/
+ }
+
mHWLightColors[cur_light] = light_color;
LLLightState* light_state = gGL.getLight(cur_light);
@@ -5912,7 +6287,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
if (sRenderDeferred)
{
F32 size = light_radius*1.5f;
- light_state->setLinearAttenuation(size*size);
+ light_state->setLinearAttenuation(size);
light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f);
}
else
@@ -5975,6 +6350,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
F32 x = 3.f;
float linatten = x / (light_radius); // % of brightness at radius
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_color.mV[0] = powf(light_color.mV[0], 2.2f);
+ light_color.mV[1] = powf(light_color.mV[1], 2.2f);
+ light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/
+ }
+
mHWLightColors[2] = light_color;
LLLightState* light = gGL.getLight(2);
@@ -6615,20 +6997,26 @@ BOOL LLPipeline::getRenderHighlights(void*)
return sRenderHighlight;
}
-LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
+// static
+void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)
+{
+ sRenderHighlightTextureChannel = channel;
+}
+
+LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
LLDrawable* drawable = NULL;
- LLVector3 local_end = end;
+ LLVector4a local_end = end;
- LLVector3 position;
+ LLVector4a position;
sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE;
@@ -6648,7 +7036,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
LLSpatialPartition* part = region->getSpatialPartition(j);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -6663,8 +7051,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
//save hit info in case we need to restore
//due to attachment override
- LLVector3 local_normal;
- LLVector3 local_binormal;
+ LLVector4a local_normal;
+ LLVector4a local_tangent;
LLVector2 local_texcoord;
S32 local_face_hit = -1;
@@ -6676,14 +7064,22 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
local_texcoord = *tex_coord;
}
- if (bi_normal)
+ if (tangent)
{
- local_binormal = *bi_normal;
+ local_tangent = *tangent;
+ }
+ else
+ {
+ local_tangent.clear();
}
if (normal)
{
local_normal = *normal;
}
+ else
+ {
+ local_normal.clear();
+ }
const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f;
@@ -6697,12 +7093,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
+ LLVector4a delta;
+ delta.setSub(position, local_end);
+
if (!drawable ||
!drawable->getVObj()->isAttachment() ||
- (position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST)
+ delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)
{ //avatar overrides if previously hit drawable is not an attachment or
//attachment is far enough away from detected intersection
drawable = hit;
@@ -6720,9 +7119,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
*tex_coord = local_texcoord;
}
- if (bi_normal)
+ if (tangent)
{
- *bi_normal = local_binormal;
+ *tangent = local_tangent;
}
if (normal)
{
@@ -6756,13 +7155,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
return drawable ? drawable->getVObj().get() : NULL;
}
-LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
+LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
LLDrawable* drawable = NULL;
@@ -6782,7 +7181,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
if (part)
{
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -6886,7 +7285,9 @@ void LLPipeline::doResetVertexBuffers()
LLVertexBuffer::unbind();
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ updateRenderBump();
+ updateRenderDeferred();
+
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
@@ -6912,6 +7313,17 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_text
gGLLastMatrix = NULL;
}
+void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)
+{
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+}
+
+
void apply_cube_face_rotation(U32 face)
{
switch (face)
@@ -7013,10 +7425,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.loadIdentity();
LLGLDisable test(GL_ALPHA_TEST);
-
+
gGL.setColorMask(true, true);
glClearColor(0,0,0,0);
-
+
{
{
LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
@@ -7188,13 +7600,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
if (LLViewerJoystick::getInstance()->getOverrideCamera())
{ //focus on point under cursor
- focus_point = gDebugRaycastIntersection;
+ focus_point.set(gDebugRaycastIntersection.getF32ptr());
}
else if (gAgentCamera.cameraMouselook())
{ //focus on point under mouselook crosshairs
+ LLVector4a result;
+ result.clear();
+
gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
NULL,
- &focus_point);
+ &result);
+
+ focus_point.set(result.getF32ptr());
}
else
{
@@ -7354,6 +7771,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
mScreen.bindTexture(0, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
+
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
@@ -7395,6 +7819,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
mScreen.bindTexture(0, channel);
}
+
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
@@ -7815,6 +8246,22 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
}
}
+LLColor3 pow3f(LLColor3 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
+LLVector4 pow4fsrgb(LLVector4 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace");
static LLFastTimer::DeclareTimer FTM_GI_GATHER("Gather");
static LLFastTimer::DeclareTimer FTM_SUN_SHADOW("Shadow Map");
@@ -7868,11 +8315,7 @@ void LLPipeline::renderDeferredLighting()
LLStrider<LLVector3> vert;
mDeferredVB->getVertexStrider(vert);
- LLStrider<LLVector2> tc0;
- LLStrider<LLVector2> tc1;
- mDeferredVB->getTexCoord0Strider(tc0);
- mDeferredVB->getTexCoord1Strider(tc1);
-
+
vert[0].set(-1,1,0);
vert[1].set(-1,-3,0);
vert[2].set(3,1,0);
@@ -8053,7 +8496,7 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::END_RENDER_TYPES);
- renderGeomPostDeferred(*LLViewerCamera::getInstance());
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
gPipeline.popRenderTypeMask();
}
@@ -8147,9 +8590,13 @@ void LLPipeline::renderDeferredLighting()
continue;
}
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
LLFastTimer ftm(FTM_LOCAL_LIGHTS);
gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
@@ -8170,7 +8617,7 @@ void LLPipeline::renderDeferredLighting()
glh::vec3f tc(c);
mat.mult_matrix_vec(tc);
- fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
+ fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
}
}
@@ -8203,9 +8650,12 @@ void LLPipeline::renderDeferredLighting()
setupSpotLight(gDeferredSpotLightProgram, drawablep);
LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
@@ -8251,9 +8701,13 @@ void LLPipeline::renderDeferredLighting()
fullscreen_lights.pop_front();
col[count] = light_colors.front();
light_colors.pop_front();
-
- far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z);
-
+
+ /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
+ col[count].mV[1] = powf(col[count].mV[1], 2.2f);
+ col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
+
+ far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
+ //col[count] = pow4fsrgb(col[count], 2.2f);
count++;
if (count == max_count || fullscreen_lights.empty())
{
@@ -8295,8 +8749,12 @@ void LLPipeline::renderDeferredLighting()
LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -8314,6 +8772,65 @@ void LLPipeline::renderDeferredLighting()
gGL.setColorMask(true, true);
}
+ mScreen.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) mScreen.getWidth()*2,
+ (F32) mScreen.getHeight()*2);
+
+ mScreen.bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ if (channel > -1)
+ {
+ mScreen.bindTexture(0,channel);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight());
+
+ F32 gamma = 1.0/2.2;
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, gamma);
+
+ 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(mScreen.getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ mScreen.flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ mScreen.bindTarget();
+
{ //render non-deferred geometry (alpha, fullbright, glow)
LLGLDisable blend(GL_BLEND);
LLGLDisable stencil(GL_STENCIL_TEST);
@@ -8338,6 +8855,8 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
@@ -8890,19 +9409,36 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_FULLBRIGHT,
LLRenderPass::PASS_SHINY,
LLRenderPass::PASS_BUMP,
- LLRenderPass::PASS_FULLBRIGHT_SHINY
+ LLRenderPass::PASS_FULLBRIGHT_SHINY ,
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
LLGLEnable cull(GL_CULL_FACE);
+ //enable depth clamping if available
+ LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
+ LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1];
+
+ occlusion_target.bindTarget();
updateCull(shadow_cam, result);
+ occlusion_target.flush();
+
stateSort(shadow_cam, result);
+
//generate shadow map
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
@@ -8961,7 +9497,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
LLFastTimer ftm(FTM_SHADOW_ALPHA);
gDeferredShadowAlphaMaskProgram.bind();
- gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
U32 mask = LLVertexBuffer::MAP_VERTEX |
@@ -8969,10 +9504,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
- renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
- renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE);
+
+ mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
+
gDeferredTreeShadowProgram.bind();
+ renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask);
+
gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
}
@@ -8982,7 +9526,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
- doOcclusion(shadow_cam);
+
+ LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1];
+
+ doOcclusion(shadow_cam, occlusion_source, occlusion_target);
if (use_shader)
{
@@ -9303,6 +9850,22 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -9822,7 +10385,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
{
static LLCullResult result[4];
- //LLGLEnable enable(GL_DEPTH_CLAMP_NV);
renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);
}
@@ -10129,11 +10691,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLVector4a left;
left.load3(camera.getLeftAxis().mV);
left.mul(left);
+ llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO);
left.normalize3fast();
LLVector4a up;
up.load3(camera.getUpAxis().mV);
up.mul(up);
+ llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO);
up.normalize3fast();
tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index a8db93585e..70dcf80407 100755
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -35,7 +35,8 @@
#include "llspatialpartition.h"
#include "m4math.h"
#include "llpointer.h"
-#include "lldrawpool.h"
+#include "lldrawpoolalpha.h"
+#include "lldrawpoolmaterials.h"
#include "llgl.h"
#include "lldrawable.h"
#include "llrendertarget.h"
@@ -59,6 +60,7 @@ class LLCullResult;
class LLVOAvatar;
class LLGLSLShader;
class LLCurlRequest;
+class LLDrawPoolAlpha;
class LLMeshResponder;
@@ -95,6 +97,7 @@ extern LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY;
extern LLFastTimer::DeclareTimer FTM_RENDER_ALPHA;
extern LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS;
extern LLFastTimer::DeclareTimer FTM_RENDER_BUMP;
+extern LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS;
extern LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT;
extern LLFastTimer::DeclareTimer FTM_RENDER_GLOW;
extern LLFastTimer::DeclareTimer FTM_STATESORT;
@@ -173,6 +176,12 @@ public:
// Object related methods
void markVisible(LLDrawable *drawablep, LLCamera& camera);
void markOccluder(LLSpatialGroup* group);
+
+ //downsample source to dest, taking the maximum depth value per pixel in source and writing to dest
+ // if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided
+ void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
+
+ void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
void doOcclusion(LLCamera& camera);
void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE);
@@ -185,21 +194,21 @@ public:
void markMeshDirty(LLSpatialGroup* group);
//get the object between start and end that's closest to start.
- LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
+ LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit, // return the face hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
- LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
+ LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit, // return the face hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
// Something about these textures has changed. Dirty them.
@@ -256,6 +265,8 @@ public:
void forAllVisibleDrawables(void (*func)(LLDrawable*));
void renderObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE);
+ void renderMaskedObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE);
+
void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture);
void grabReferences(LLCullResult& result);
@@ -270,7 +281,7 @@ public:
void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE);
void renderGeomDeferred(LLCamera& camera);
- void renderGeomPostDeferred(LLCamera& camera);
+ void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
void renderGeomShadow(LLCamera& camera);
void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, U32 noise_map = 0xFFFFFFFF);
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
@@ -389,12 +400,16 @@ public:
static void setRenderHighlights(BOOL val);
static void toggleRenderHighlights(void* data);
static BOOL getRenderHighlights(void* data);
+ static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay
+ static void updateRenderBump();
static void updateRenderDeferred();
static void refreshCachedSettings();
static void throttleNewMemoryAllocation(BOOL disable);
+
+
void addDebugBlip(const LLVector3& position, const LLColor4& color);
void hidePermanentObjects( std::vector<U32>& restoreList );
@@ -425,8 +440,11 @@ public:
RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN,
RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE,
RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS,
+ RENDER_TYPE_ALPHA_MASK = LLDrawPool::POOL_ALPHA_MASK,
+ RENDER_TYPE_FULLBRIGHT_ALPHA_MASK = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK,
RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT,
RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP,
+ RENDER_TYPE_MATERIALS = LLDrawPool::POOL_MATERIALS,
RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE,
@@ -447,6 +465,22 @@ public:
RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK,
+ RENDER_TYPE_PASS_MATERIAL = LLRenderPass::PASS_MATERIAL,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA = LLRenderPass::PASS_MATERIAL_ALPHA,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK = LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ RENDER_TYPE_PASS_SPECMAP = LLRenderPass::PASS_SPECMAP,
+ RENDER_TYPE_PASS_SPECMAP_BLEND = LLRenderPass::PASS_SPECMAP_BLEND,
+ RENDER_TYPE_PASS_SPECMAP_MASK = LLRenderPass::PASS_SPECMAP_MASK,
+ RENDER_TYPE_PASS_SPECMAP_EMISSIVE = LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ RENDER_TYPE_PASS_NORMMAP = LLRenderPass::PASS_NORMMAP,
+ RENDER_TYPE_PASS_NORMMAP_BLEND = LLRenderPass::PASS_NORMMAP_BLEND,
+ RENDER_TYPE_PASS_NORMMAP_MASK = LLRenderPass::PASS_NORMMAP_MASK,
+ RENDER_TYPE_PASS_NORMMAP_EMISSIVE = LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ RENDER_TYPE_PASS_NORMSPEC = LLRenderPass::PASS_NORMSPEC,
+ RENDER_TYPE_PASS_NORMSPEC_BLEND = LLRenderPass::PASS_NORMSPEC_BLEND,
+ RENDER_TYPE_PASS_NORMSPEC_MASK = LLRenderPass::PASS_NORMSPEC_MASK,
+ RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
RENDER_TYPE_VOLUME,
@@ -562,7 +596,8 @@ public:
static BOOL sRenderDeferred;
static BOOL sMemAllocationThrottled;
static S32 sVisibleLightCount;
- static F32 sMinRenderSize;
+ static F32 sMinRenderSize;
+ static BOOL sRenderingHUDs;
//screen texture
U32 mScreenWidth;
@@ -574,6 +609,7 @@ public:
LLRenderTarget mFXAABuffer;
LLRenderTarget mEdgeMap;
LLRenderTarget mDeferredDepth;
+ LLRenderTarget mOcclusionDepth;
LLRenderTarget mDeferredLight;
LLRenderTarget mHighlight;
LLRenderTarget mPhysicsDisplay;
@@ -586,6 +622,7 @@ public:
//sun shadow map
LLRenderTarget mShadow[6];
+ LLRenderTarget mShadowOcclusion[6];
std::vector<LLVector3> mShadowFrustPoints[4];
LLVector4 mShadowError;
LLVector4 mShadowFOV;
@@ -773,17 +810,20 @@ protected:
// For quick-lookups into mPools (mapped by texture pointer)
std::map<uintptr_t, LLDrawPool*> mTerrainPools;
std::map<uintptr_t, LLDrawPool*> mTreePools;
- LLDrawPool* mAlphaPool;
+ 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;
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
@@ -822,6 +862,10 @@ public:
static BOOL sRenderBeacons;
static BOOL sRenderHighlight;
+ // Determines which set of UVs to use in highlight display
+ //
+ static LLRender::eTexIndex sRenderHighlightTextureChannel;
+
//debug use
static U32 sCurRenderPoolType ;
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 42568775d9..a9176595c7 100755
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -657,6 +657,15 @@
name="PathfindingGoodColor"
reference="LtGreen" />
<color
+ name="MaterialErrorColor"
+ reference="LtRed" />
+ <color
+ name="MaterialWarningColor"
+ reference="DrYellow" />
+ <color
+ name="MaterialGoodColor"
+ reference="LtGreen" />
+ <color
name="PathfindingDefaultBeaconColor"
reference="Red_80" />
<color
diff --git a/indra/newview/skins/default/textures/flatnormal.tga b/indra/newview/skins/default/textures/flatnormal.tga
new file mode 100644
index 0000000000..6d5abd1782
--- /dev/null
+++ b/indra/newview/skins/default/textures/flatnormal.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/materials_ui_x_24.png b/indra/newview/skins/default/textures/materials_ui_x_24.png
new file mode 100644
index 0000000000..6d88554914
--- /dev/null
+++ b/indra/newview/skins/default/textures/materials_ui_x_24.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index fcab966dee..b0e4b71d21 100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -743,6 +743,7 @@ with the same filename but different name
<texture name="default_land_picture.j2c" />
<texture name="default_profile_picture.j2c" />
<texture name="locked_image.j2c" />
+ <texture name="materials_ui_x_24.png" />
<texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" />
<texture name="Progress_2" file_name="icons/Progress_2.png" preload="true" />
diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml
index d695cd1f89..f2ed7c2e64 100755
--- a/indra/newview/skins/default/xui/da/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/da/menu_viewer.xml
@@ -245,7 +245,7 @@
<menu label="Gengivelse" name="Rendering">
<menu_item_check label="Akser" name="Axes"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Lys og skygger" name="Lighting and Shadows"/>
+ <menu_item_check label="Lys og skygger" name="Advanced Lighting Model"/>
<menu_item_check label="Skygger fra sol/måne/andre lyskilder" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO og skygge udjævning" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Globalt lys (eksperimentiel)" name="Global Illumination"/>
diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index 2c9d9fa7f1..47d9fec352 100755
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -315,7 +315,7 @@
<menu_item_call label="Texturinfo für ausgewähltes Objekt" name="Selected Texture Info Basis"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
<menu_item_check label="Objekt-Objekt Okklusion" name="Object-Object Occlusion"/>
- <menu_item_check label="Licht und Schatten" name="Lighting and Shadows"/>
+ <menu_item_check label="Uber Licht Modell" name="Advanced Lighting Model"/>
<menu_item_check label="Schatten von Sonne-/Mond-Projektoren" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO und Schattenglättung" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Fehler in GL beseitigen" name="Debug GL"/>
@@ -393,14 +393,9 @@
<menu_item_call label="Weiblich testen" name="Test Female"/>
<menu_item_check label="Avatarauswahl zulassen" name="Allow Select Avatar"/>
</menu>
- <menu label="Animationsgeschwindigkeit" name="Animation Speed">
- <menu_item_call label="Alle Animationen 10 % schneller" name="All Animations 10 Faster"/>
- <menu_item_call label="Alle Animationen 10 % langsamer" name="All Animations 10 Slower"/>
- <menu_item_call label="Alle Animationsgeschwindigkeiten zurücksetzen" name="Reset All Animation Speed"/>
- <menu_item_check label="Zeitlupen-Animationen" name="Slow Motion Animations"/>
- </menu>
<menu_item_call label="Param auf Standard erzwingen" name="Force Params to Default"/>
<menu_item_check label="Animations-Info" name="Animation Info"/>
+ <menu_item_check label="Zeitlupen-Animationen" name="Slow Motion Animations"/>
<menu_item_check label="Kamerafokus anzeigen" name="Show Look At"/>
<menu_item_check label="Klickpunkt anzeigen??" name="Show Point At"/>
<menu_item_check label="Fehler in Landaktualisierung beseitigen" name="Debug Joint Updates"/>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 436e9f8fed..8b9733df17 100755
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2491,534 +2491,10 @@ even though the user gets a free copy.
width="132" />
</panel>
<panel
- border="false"
- follows="all"
- height="367"
label="Texture"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
help_topic="toolbox_texture_tab"
name="Texture"
- top_delta="0"
- width="295">
- <panel.string
- name="string repeats per meter">
- Repeats Per Meter
- </panel.string>
- <panel.string
- name="string repeats per face">
- Repeats Per Face
- </panel.string>
- <texture_picker
- can_apply_immediately="true"
- default_image_name="Default"
- fallback_image="locked_image.j2c"
- follows="left|top"
- height="80"
- label="Texture"
- layout="topleft"
- left="10"
- name="texture control"
- tool_tip="Click to choose a picture"
- top="8"
- width="64" />
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="80"
- label="Color"
- layout="topleft"
- left_pad="15"
- name="colorswatch"
- tool_tip="Click to open color picker"
- top_delta="0"
- width="64" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="15"
- name="color trans"
- text_readonly_color="LabelDisabledColor"
- top="6"
- width="110">
- Transparency %
- </text>
- <spinner
- decimal_digits="0"
- follows="left|top"
- height="19"
- increment="2"
- initial_value="0"
- layout="topleft"
- left_delta="0"
- max_val="100"
- name="ColorTrans"
- top_pad="4"
- width="80" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="0"
- name="glow label"
- text_readonly_color="LabelDisabledColor"
- top_pad="8"
- width="80">
- Glow
- </text>
- <spinner
- decimal_digits="2"
- follows="left|top"
- height="19"
- initial_value="0"
- layout="topleft"
- left_delta="0"
- name="glow"
- top_pad="4"
- width="80" />
- <check_box
- height="19"
- label="Full Bright"
- layout="topleft"
- left_delta="-5"
- name="checkbox fullbright"
- top_pad="4"
- width="81" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="tex gen"
- text_readonly_color="LabelDisabledColor"
- top_pad="5"
- width="90">
- Mapping
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox texgen"
- top_pad="4"
- width="90">
- <combo_box.item
- label="Default"
- name="Default"
- value="Default" />
- <combo_box.item
- label="Planar"
- name="Planar"
- value="Planar" />
- </combo_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- name="label shininess"
- left_pad="4"
- text_readonly_color="LabelDisabledColor"
- top_pad="-37"
- width="90">
- Shininess
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox shininess"
- top_pad="4"
- width="90">
- <combo_box.item
- label="None"
- name="None"
- value="None" />
- <combo_box.item
- label="Low"
- name="Low"
- value="Low" />
- <combo_box.item
- label="Medium"
- name="Medium"
- value="Medium" />
- <combo_box.item
- label="High"
- name="High"
- value="High" />
- </combo_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="4"
- name="label bumpiness"
- text_readonly_color="LabelDisabledColor"
- top_pad="-37"
- width="90">
- Bumpiness
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox bumpiness"
- top_pad="4"
- width="90">
- <combo_box.item
- label="None"
- name="None"
- value="None" />
- <combo_box.item
- label="Brightness"
- name="Brightness"
- value="Brightness" />
- <combo_box.item
- label="Darkness"
- name="Darkness"
- value="Darkness" />
- <combo_box.item
- label="woodgrain"
- name="woodgrain"
- value="woodgrain" />
- <combo_box.item
- label="bark"
- name="bark"
- value="bark" />
- <combo_box.item
- label="bricks"
- name="bricks"
- value="bricks" />
- <combo_box.item
- label="checker"
- name="checker"
- value="checker" />
- <combo_box.item
- label="concrete"
- name="concrete"
- value="concrete" />
- <combo_box.item
- label="crustytile"
- name="crustytile"
- value="crustytile" />
- <combo_box.item
- label="cutstone"
- name="cutstone"
- value="cutstone" />
- <combo_box.item
- label="discs"
- name="discs"
- value="discs" />
- <combo_box.item
- label="gravel"
- name="gravel"
- value="gravel" />
- <combo_box.item
- label="petridish"
- name="petridish"
- value="petridish" />
- <combo_box.item
- label="siding"
- name="siding"
- value="siding" />
- <combo_box.item
- label="stonetile"
- name="stonetile"
- value="stonetile" />
- <combo_box.item
- label="stucco"
- name="stucco"
- value="stucco" />
- <combo_box.item
- label="suction"
- name="suction"
- value="suction" />
- <combo_box.item
- label="weave"
- name="weave"
- value="weave" />
- </combo_box>
- <!--
- <line_editor
- bevel_style="in"
- border_style="line"
- border_thickness="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- max_length_bytes="63"
- name="Home Url"
- select_on_focus="true"
- top="134"
- width="250" />
- <check_box
- height="16"
- label="Media Face"
- layout="topleft"
- left_delta="0"
- name="has media"
- top_pad="6"
- width="70" />
- <button
- follows="left|top"
- font="SansSerifSmall"
- height="20"
- label="Set Media Info"
- label_selected="Set Media Info"
- layout="topleft"
- left_pad="60"
- name="media info set"
- top_delta="-4"
- width="120" />
--->
- <check_box
- follows="top|left"
- height="16"
- initial_value="false"
- label="Align planar faces"
- layout="topleft"
- left="17"
- name="checkbox planar align"
- tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."
- top_delta="26"
- width="140" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="rpt"
- text_readonly_color="LabelDisabledColor"
- top_pad="2"
- width="140">
- Repeats / Face
- </text>
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Horizontal (U)"
- label_width="125"
- layout="topleft"
- left="20"
- max_val="100"
- name="TexScaleU"
- top_pad="5"
- width="185" />
- <check_box
- height="19"
- label="Flip"
- layout="topleft"
- left_pad="5"
- name="checkbox flip s"
- top_delta="0"
- width="70" />
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Vertical (V)"
- label_width="125"
- layout="topleft"
- left="20"
- max_val="100"
- name="TexScaleV"
- width="185" />
- <check_box
- height="19"
- label="Flip"
- layout="topleft"
- left_pad="5"
- name="checkbox flip t"
- top_delta="0"
- width="70" />
- <spinner
- decimal_digits="2"
- follows="left|top"
- height="19"
- increment="1"
- initial_value="0"
- label="Rotation˚"
- layout="topleft"
- label_width="135"
- left="10"
- max_val="9999"
- min_val="-9999"
- name="TexRot"
- width="195" />
-
- <spinner
- decimal_digits="1"
- follows="left|top"
- height="23"
- initial_value="1"
- label="Repeats / Meter"
- layout="topleft"
- label_width="135"
- left="10"
- max_val="10"
- min_val="0.1"
- name="rptctrl"
- width="195" />
- <button
- follows="left|top"
- height="23"
- label="Apply"
- label_selected="Apply"
- layout="topleft"
- left_pad="5"
- name="button apply"
- width="75" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="tex offset"
- text_readonly_color="LabelDisabledColor"
- width="200">
- Texture Offset
- </text>
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Horizontal (U)"
- label_width="125"
- layout="topleft"
- left="20"
- min_val="-1"
- name="TexOffsetU"
- width="185" />
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Vertical (V)"
- label_width="125"
- layout="topleft"
- left_delta="0"
- min_val="-1"
- name="TexOffsetV"
- top_pad="1"
- width="185" />
- <panel
- border="false"
- follows="left|top"
- layout="topleft"
- mouse_opaque="false"
- background_visible="true"
- bg_alpha_color="DkGray"
- name="Add_Media"
- left="0"
- height="47"
- width="290">
- <text
- type="string"
- length="1"
- follows="left|top"
- height="18"
- layout="topleft"
- left="10"
- top_pad="3"
- name="media_tex"
- width="190">
- Media
- </text>
- <button
- follows="top|left"
- height="18"
- image_selected="AddItem_Press"
- image_unselected="AddItem_Off"
- image_disabled="AddItem_Disabled"
- layout="topleft"
- left_pad="0"
- name="add_media"
- tab_stop="false"
- top_delta="0"
- tool_tip="Add Media"
- width="18">
- <button.commit_callback
- function="BuildTool.AddMedia"/>
- </button>
- <button
- follows="top|left"
- height="18"
- image_selected="TrashItem_Press"
- image_unselected="TrashItem_Off"
- layout="topleft"
- left_pad="5"
- name="delete_media"
- tool_tip="Delete this media texture"
- top_delta="0"
- width="18">
- <button.commit_callback
- function="BuildTool.DeleteMedia"/>
- </button>
- <button
- follows="top|left"
- tool_tip="Edit this Media"
- height="12"
- image_disabled="Icon_Gear_Background"
- image_selected="Icon_Gear_Press"
- image_unselected="Icon_Gear_Foreground"
- layout="topleft"
- left_pad="10"
- name="edit_media"
- top_delta="3"
- width="12">
- <button.commit_callback
- function="BuildTool.EditMedia"/>
- </button>
- <text
- follows="left|top|right"
- height="9"
- layout="topleft"
- left="10"
- use_ellipses="true"
- read_only="true"
- name="media_info"
- width="180" />
- <web_browser
- visible="false"
- enabled="false"
- border_visible="true"
- bottom_delta="0"
- follows="top|left"
- left="0"
- name="title_media"
- width="4"
- height="4"
- start_url="about:blank"
- decouple_texture_size="true" />
- <button
- follows="right|top"
- height="22"
- label="Align"
- label_selected="Align Media"
- layout="topleft"
- right="-16"
- name="button align"
- top_delta="-4"
- tool_tip="Align media texture (must load first)"
- width="80" />
- </panel>
+ filename="panel_tools_texture.xml">
</panel>
<panel
border="false"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index a11cd13fdb..b01c3067ff 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2363,6 +2363,12 @@
<menu_item_check.on_click
function="Advanced.ToggleFrameTest" />
</menu_item_check>
+ <menu_item_call
+ label="Frame Profile"
+ name="Frame Profile">
+ <menu_item_call.on_click
+ function="Advanced.ClickRenderProfile" />
+ </menu_item_call>
</menu>
<menu
create_jump_keys="true"
@@ -2658,6 +2664,13 @@
<menu_item_call.on_click
function="Advanced.SelectedTextureInfo" />
</menu_item_call>
+ <menu_item_call
+ label="Selected Material Info"
+ name="Selected Material Info"
+ shortcut="control|alt|shift|M">
+ <menu_item_call.on_click
+ function="Advanced.SelectedMaterialInfo" />
+ </menu_item_call>
<menu_item_check
label="Wireframe"
name="Wireframe"
@@ -2684,8 +2697,8 @@
<menu_item_separator />
<menu_item_check
- label="Lighting and Shadows"
- name="Lighting and Shadows">
+ label="Advanced Lighting Model"
+ name="Advanced Lighting Model">
<menu_item_check.on_check
function="CheckControl"
parameter="RenderDeferred" />
@@ -2792,16 +2805,6 @@
parameter="TextureLoadFullRes" />
</menu_item_check>
<menu_item_check
- label="Texture Atlas (experimental)"
- name="Texture Atlas">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="EnableTextureAtlas" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="EnableTextureAtlas" />
- </menu_item_check>
- <menu_item_check
label="Render Attached Lights"
name="Render Attached Lights">
<menu_item_check.on_check
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index c3d8a528c5..7c29664156 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3454,7 +3454,7 @@ or you can install it now.
name="DownloadBackgroundTip"
type="notify">
We have downloaded an update to your [APP_NAME] installation.
-Version [VERSION] [[INFO_URL] Information about this update]
+Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
@@ -3467,7 +3467,7 @@ Version [VERSION] [[INFO_URL] Information about this update]
name="DownloadBackgroundDialog"
type="alertmodal">
We have downloaded an update to your [APP_NAME] installation.
-Version [VERSION] [[INFO_URL] Information about this update]
+Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
@@ -6923,9 +6923,9 @@ Do not allow access if you do not fully understand why it wants access to your a
[FOOTERTEXT]
</footer>
</notification>
-
- <notification
- icon="notify.tga"
+
+ <notification
+ icon="notify.tga"
name="UnknownScriptQuestion"
persist="false"
type="notify">
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 cd243d40a4..d7db7caf66 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -211,16 +211,19 @@
name="TransparentWater"
top_pad="7"
width="256" />
- <check_box
- control_name="RenderObjectBump"
- height="16"
- initial_value="true"
- label="Bump mapping and shiny"
- layout="topleft"
- left_delta="0"
- name="BumpShiny"
- top_pad="1"
- width="256" />
+ <check_box
+ control_name="RenderObjectBump"
+ height="16"
+ initial_value="true"
+ label="Bump mapping and shiny"
+ layout="topleft"
+ left_delta="0"
+ name="BumpShiny"
+ top_pad="1"
+ width="256">
+ <check_box.commit_callback
+ function="Pref.VertexShaderEnable" />
+ </check_box>
<check_box
control_name="RenderLocalLights"
height="16"
@@ -262,7 +265,7 @@
control_name="RenderDeferred"
height="16"
initial_value="true"
- label="Lighting and Shadows"
+ label="Advanced Lighting Model"
layout="topleft"
left_delta="0"
name="UseLightShaders"
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
new file mode 100644
index 0000000000..5ac2ec2b20
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -0,0 +1,766 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="false"
+ follows="all"
+ height="420"
+ label="Texture"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ help_topic="toolbox_texture_tab"
+ name="Texture"
+ top="0"
+ width="295">
+ <panel.string
+ name="string repeats per meter">
+ Repeats Per Meter
+ </panel.string>
+ <panel.string
+ name="string repeats per face">
+ Repeats Per Face
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="color label"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="64">
+ Color
+ </text>
+ <!-- label is blank because control places it below the box -->
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="45"
+ label=""
+ layout="topleft"
+ left="10"
+ name="colorswatch"
+ tool_tip="Click to open color picker"
+ top="20"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="15"
+ name="color trans"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="110">
+ Transparency %
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="19"
+ increment="2"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="ColorTrans"
+ top_pad="4"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="15"
+ name="glow label"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="80">
+ Glow
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ name="glow"
+ top_pad="4"
+ width="80" />
+ <check_box
+ height="19"
+ label="Full Bright"
+ layout="topleft"
+ left="7"
+ name="checkbox fullbright"
+ top_pad="4"
+ width="81" />
+ <combo_box
+ height="23"
+ layout="topleft"
+ left="10"
+ name="combobox matmedia"
+ top_pad="5"
+ width="100">
+ <combo_box.item
+ label="Materials"
+ name="Materials"
+ value="Materials" />
+ <combo_box.item
+ label="Media"
+ name="Media"
+ value="Media" />
+ </combo_box>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ name="combobox mattype"
+ top_delta="0"
+ width="155">
+ <combo_box.item
+ label="Texture (diffuse)"
+ name="Texture (diffuse)"
+ value="Texture (diffuse)" />
+ <combo_box.item
+ label="Bumpiness (normal)"
+ name="Bumpiness (normal)"
+ value="Bumpiness (normal)" />
+ <combo_box.item
+ label="Shininess (specular)"
+ name="Shininess (specular)"
+ value="Shininess (specular)" />
+ </combo_box>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ height="80"
+ label="Texture "
+ layout="topleft"
+ left="10"
+ name="texture control"
+ tool_tip="Click to choose a picture"
+ top_pad="8"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ name="label alphamode"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="0"
+ width="90">
+ Alpha mode
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="combobox alphamode"
+ top_pad="4"
+ width="120">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Alpha blending"
+ name="Alpha blending"
+ value="Alpha blending" />
+ <combo_box.item
+ label="Alpha masking"
+ name="Alpha masking"
+ value="Alpha masking" />
+ <combo_box.item
+ label="Emissive mask"
+ name="Emissive mask"
+ value="Emissive mask" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label maskcutoff"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="4"
+ width="90">
+ Mask cutoff
+ </text>
+ <spinner
+ decimal_digits="0"
+ min_val="0"
+ max_val="255"
+ follows="left|top"
+ height="19"
+ initial_value="55"
+ layout="topleft"
+ top_pad="4"
+ left_delta="0"
+ increment="1"
+ name="maskcutoff"
+ width="80" />
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ height="80"
+ label="Texture "
+ layout="topleft"
+ left="10"
+ name="bumpytexture control"
+ tool_tip="Click to choose a picture"
+ top_delta="-55"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ name="label bumpiness"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="0"
+ width="90">
+ Bumpiness
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="combobox bumpiness"
+ top_pad="4"
+ width="90">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Brightness"
+ name="Brightness"
+ value="Brightness" />
+ <combo_box.item
+ label="Darkness"
+ name="Darkness"
+ value="Darkness" />
+ <combo_box.item
+ label="woodgrain"
+ name="woodgrain"
+ value="woodgrain" />
+ <combo_box.item
+ label="bark"
+ name="bark"
+ value="bark" />
+ <combo_box.item
+ label="bricks"
+ name="bricks"
+ value="bricks" />
+ <combo_box.item
+ label="checker"
+ name="checker"
+ value="checker" />
+ <combo_box.item
+ label="concrete"
+ name="concrete"
+ value="concrete" />
+ <combo_box.item
+ label="crustytile"
+ name="crustytile"
+ value="crustytile" />
+ <combo_box.item
+ label="cutstone"
+ name="cutstone"
+ value="cutstone" />
+ <combo_box.item
+ label="discs"
+ name="discs"
+ value="discs" />
+ <combo_box.item
+ label="gravel"
+ name="gravel"
+ value="gravel" />
+ <combo_box.item
+ label="petridish"
+ name="petridish"
+ value="petridish" />
+ <combo_box.item
+ label="siding"
+ name="siding"
+ value="siding" />
+ <combo_box.item
+ label="stonetile"
+ name="stonetile"
+ value="stonetile" />
+ <combo_box.item
+ label="stucco"
+ name="stucco"
+ value="stucco" />
+ <combo_box.item
+ label="suction"
+ name="suction"
+ value="suction" />
+ <combo_box.item
+ label="weave"
+ name="weave"
+ value="weave" />
+ <!--
+ NORSPEC-182, ensure item doesn't show up in menu until it should
+ <combo_box.item
+ label="Use texture"
+ name="Use texture"
+ value="Use texture" />
+ -->
+ </combo_box>
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ height="80"
+ label="Texture "
+ layout="topleft"
+ left="10"
+ name="shinytexture control"
+ tool_tip="Click to choose a picture"
+ top_delta="-14"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ name="label shininess"
+ left_pad="10"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="6"
+ width="90">
+ Shininess
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ name="combobox shininess"
+ top_delta="-6"
+ width="90">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Low"
+ name="Low"
+ value="Low" />
+ <combo_box.item
+ label="Medium"
+ name="Medium"
+ value="Medium" />
+ <combo_box.item
+ label="High"
+ name="High"
+ value="High" />
+ <!--
+ NORSPEC-182, ensure item doesn't show up in menu until it should
+ <combo_box.item
+ label="Use texture"
+ name="Use texture"
+ value="Use texture" />
+ -->
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-100"
+ name="label glossiness"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="8"
+ width="116">
+ Glossiness
+ </text>
+ <spinner
+ decimal_digits="0"
+ min_val="0"
+ max_val="255"
+ follows="left|top"
+ height="19"
+ initial_value="51"
+ increment="1"
+ layout="topleft"
+ top_delta="-4"
+ left_pad="10"
+ name="glossiness"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-126"
+ name="label environment"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="8"
+ width="116">
+ Environment
+ </text>
+ <spinner
+ decimal_digits="0"
+ min_val="0"
+ max_val="255"
+ increment="1"
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ layout="topleft"
+ top_delta="-4"
+ left_pad="10"
+ name="environment"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-126"
+ name="label shinycolor"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="8"
+ width="116">
+ Color
+ </text>
+ <!-- label is blank because control places it below the box -->
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="45"
+ label=""
+ layout="topleft"
+ left_pad="10"
+ name="shinycolorswatch"
+ tool_tip="Click to open color picker"
+ top_delta="-4"
+ width="64" />
+ <text
+ follows="left|top|right"
+ height="9"
+ layout="topleft"
+ left="10"
+ top_delta="-50"
+ use_ellipses="true"
+ read_only="true"
+ name="media_info"
+ width="280">
+ URL of chosen media, if any, goes here
+ </text>
+ <button
+ follows="top|left"
+ height="18"
+ layout="topleft"
+ left="10"
+ name="add_media"
+ top_pad="4"
+ tool_tip="Add Media"
+ label="Choose..."
+ width="85">
+ <button.commit_callback
+ function="BuildTool.AddMedia"/>
+ </button>
+ <button
+ follows="top|left"
+ height="18"
+ layout="topleft"
+ left_pad="5"
+ name="delete_media"
+ tool_tip="Delete this media texture"
+ top_delta="0"
+ label="Remove"
+ width="85">
+ <button.commit_callback
+ function="BuildTool.DeleteMedia"/>
+ </button>
+ <button
+ follows="left|top"
+ height="18"
+ label="Align"
+ label_selected="Align Media"
+ layout="topleft"
+ left_pad="5"
+ name="button align"
+ top_delta="0"
+ tool_tip="Align media texture (must load first)"
+ width="85" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="tex gen"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="60"
+ width="140">
+ Mapping
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="0"
+ name="combobox texgen"
+ top_pad="-13"
+ width="125">
+ <combo_box.item
+ label="Default"
+ name="Default"
+ value="Default" />
+ <combo_box.item
+ label="Planar"
+ name="Planar"
+ value="Planar" />
+ </combo_box>
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="TexScaleU"
+ top_pad="5"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="TexScaleV"
+ width="265" />
+ <spinner
+ decimal_digits="1"
+ follows="left|top"
+ height="19"
+ initial_value=""
+ label="Repeats per meter"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="100"
+ min_val="0.1"
+ name="rptctrl"
+ width="265" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="1"
+ initial_value="0"
+ label="Rotation degrees"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="9999"
+ min_val="-9999"
+ name="TexRot"
+ width="265" />
+
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="TexOffsetU"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="TexOffsetV"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="bumpyScaleU"
+ top_delta="-115"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="bumpyScaleV"
+ width="265" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ top_pad="27"
+ increment="1"
+ initial_value="0"
+ label="Rotation degrees"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="360"
+ min_val="0"
+ name="bumpyRot"
+ width="265" />
+
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="bumpyOffsetU"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="bumpyOffsetV"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="shinyScaleU"
+ top_delta="-115"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="shinyScaleV"
+ width="265" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ top_pad="27"
+ increment="1"
+ initial_value="0"
+ label="Rotation degrees"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="360"
+ min_val="0"
+ name="shinyRot"
+ width="265" />
+
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="shinyOffsetU"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="shinyOffsetV"
+ width="265" />
+ <check_box
+ follows="top|left"
+ height="16"
+ initial_value="false"
+ label="Align planar faces"
+ layout="topleft"
+ left="7"
+ name="checkbox planar align"
+ tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."
+ top_delta="16"
+ width="260" />
+ <web_browser
+ visible="false"
+ enabled="false"
+ border_visible="true"
+ bottom_delta="0"
+ follows="top|left"
+ left="0"
+ name="title_media"
+ width="4"
+ height="4"
+ start_url="about:blank"
+ decouple_texture_size="true" />
+ </panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 3b57ff5fd6..f7b33b0a4a 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -373,6 +373,8 @@ Please try logging in again in a minute.</string>
<!-- build floater -->
<string name="multiple_textures">Multiple</string>
+<string name="use_texture">Use texture</string>
+
<!-- world map -->
<string name="texture_loading">Loading...</string>
<string name="worldmap_offline">Offline</string>
@@ -416,7 +418,7 @@ Please try logging in again in a minute.</string>
<string name="OverrideYourAnimations">Replace your default animations</string>
<string name="ScriptReturnObjects">Return objects on your behalf</string>
<string name="UnknownScriptPermission">(unknown)!</string>
-
+
<!-- Sim Access labels -->
<string name="SIM_ACCESS_PG">General</string>
<string name="SIM_ACCESS_MATURE">Moderate</string>
diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml
index 30842f53f2..1e0ceb2220 100755
--- a/indra/newview/skins/default/xui/es/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/es/menu_viewer.xml
@@ -293,7 +293,7 @@
<menu label="Rendering" name="Rendering">
<menu_item_check label="Axes" name="Axes"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Luces y sombras" name="Lighting and Shadows"/>
+ <menu_item_check label="Luces y sombras" name="Advanced Lighting Model"/>
<menu_item_check label="Sombras del sol/la luna/proyectores" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO y sombras suavizadas" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Capas alfa automáticas (deferidas)" name="Automatic Alpha Masks (deferred)"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 457b756c7d..548f144742 100755
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -315,7 +315,7 @@
<menu_item_call label="Base des infos de la texture sélectionnée" name="Selected Texture Info Basis"/>
<menu_item_check label="Filaire" name="Wireframe"/>
<menu_item_check label="Occlusion objet-objet" name="Object-Object Occlusion"/>
- <menu_item_check label="Éclairage et ombres" name="Lighting and Shadows"/>
+ <menu_item_check label="Éclairage et ombres" name="Advanced Lighting Model"/>
<menu_item_check label="Ombres du soleil/de la lune/des projecteurs" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO et lissage des ombres" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Débogage GL" name="Debug GL"/>
diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml
index c93b92029f..2b7bc71df7 100755
--- a/indra/newview/skins/default/xui/it/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/it/menu_viewer.xml
@@ -294,7 +294,7 @@
<menu label="Rendering" name="Rendering">
<menu_item_check label="Assi" name="Axes"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Luci e ombre" name="Lighting and Shadows"/>
+ <menu_item_check label="Luci e ombre" name="Advanced Lighting Model"/>
<menu_item_check label="Ombra dal sole, dalla luna e dai proiettori" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO e ombre fluide" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Maschera alfa automatica (differita)" name="Automatic Alpha Masks (deferred)"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml
index 6f650242b4..89f58d3bac 100755
--- a/indra/newview/skins/default/xui/ja/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml
@@ -315,7 +315,7 @@
<menu_item_call label="選択したテクスチャ情報基底" name="Selected Texture Info Basis"/>
<menu_item_check label="ワイヤーフレーム" name="Wireframe"/>
<menu_item_check label="オブジェクト間オクルージョン" name="Object-Object Occlusion"/>
- <menu_item_check label="光と影" name="Lighting and Shadows"/>
+ <menu_item_check label="光と影" name="Advanced Lighting Model"/>
<menu_item_check label="太陽・月・プロジェクタからの影" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO と影の平滑化" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="GL デバッグ" name="Debug GL"/>
diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml
index 24c961fa26..e1725fc308 100755
--- a/indra/newview/skins/default/xui/pl/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml
@@ -236,7 +236,7 @@
<menu label="Renderowanie" name="Rendering">
<menu_item_check label="Osie" name="Axes"/>
<menu_item_check label="Tryb obrazu szkieletowego" name="Wireframe"/>
- <menu_item_check label="Oświetlenie i cienie" name="Lighting and Shadows"/>
+ <menu_item_check label="Oświetlenie i cienie" name="Advanced Lighting Model"/>
<menu_item_check label="Cienie Słońca/Księżyca/Projektory" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO and wygładzanie cienia" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Globalne oświetlenie (eksperymentalne)" name="Global Illumination"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml
index 703df84efb..15814fed4c 100755
--- a/indra/newview/skins/default/xui/pt/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml
@@ -294,7 +294,7 @@
<menu label="Rendering" name="Rendering">
<menu_item_check label="Axes" name="Axes"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Iluminação e sombras" name="Lighting and Shadows"/>
+ <menu_item_check label="Iluminação e sombras" name="Advanced Lighting Model"/>
<menu_item_check label="Sombras da projeção do sol/lua" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO e sombra suave" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Máscaras alpha automáticas (adiadas)" name="Automatic Alpha Masks (deferred)"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml
index d6625361c5..92a9943b93 100755
--- a/indra/newview/skins/default/xui/ru/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml
@@ -114,6 +114,7 @@
<menu_item_call label="Купить" name="Menu Object Buy"/>
<menu_item_call label="Взять" name="Menu Object Take"/>
<menu_item_call label="Взять копию" name="Take Copy"/>
+ <menu_item_call label="Сохранить в моем инвентаре" name="Save Object Back to My Inventory"/>
<menu_item_call label="Сохранить в контенте объектов" name="Save Object Back to Object Contents"/>
<menu_item_call label="Вернуть объект" name="Return Object back to Owner"/>
</menu>
@@ -128,7 +129,6 @@
<menu_item_call label="Наборы связей..." name="pathfinding_linksets_menu_item"/>
<menu_item_call label="Персонажи..." name="pathfinding_characters_menu_item"/>
<menu_item_call label="Просмотр/тестирование..." name="pathfinding_console_menu_item"/>
- <menu_item_call label="Восстановить регион" name="pathfinding_rebake_navmesh_item"/>
</menu>
<menu label="Параметры" name="Options">
<menu_item_check label="Показать расширенные разрешения" name="DebugPermissions"/>
@@ -158,13 +158,6 @@
<menu label="Справка" name="Help">
<menu_item_call label="Инструкции..." name="How To"/>
<menu_item_call label="Справка по [SECOND_LIFE]" name="Second Life Help"/>
- <menu_item_call label="Руководство пользователя" name="User’s guide"/>
- <menu_item_call label="База знаний" name="Knowledge Base"/>
- <menu_item_call label="Wiki" name="Wiki"/>
- <menu_item_call label="Форумы сообщества" name="Community Forums"/>
- <menu_item_call label="Портал поддержки" name="Support portal"/>
- <menu_item_call label="Новости [SECOND_LIFE]" name="Second Life News"/>
- <menu_item_call label="Блоги [SECOND_LIFE]" name="Second Life Blogs"/>
<menu_item_call label="Жалоба" name="Report Abuse"/>
<menu_item_call label="Сообщить об ошибке" name="Report Bug"/>
<menu_item_call label="О [APP_NAME]" name="About Second Life"/>
@@ -313,7 +306,7 @@
<menu_item_call label="Выбранная текстура в основе" name="Selected Texture Info Basis"/>
<menu_item_check label="Каркас" name="Wireframe"/>
<menu_item_check label="Смыкание объектов" name="Object-Object Occlusion"/>
- <menu_item_check label="Освещение и тени" name="Lighting and Shadows"/>
+ <menu_item_check label="Освещение и тени" name="Advanced Lighting Model"/>
<menu_item_check label="Тени от солнца, луны и прожекторов" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO и сглаживание теней" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Отладка GL" name="Debug GL"/>
@@ -391,14 +384,9 @@
<menu_item_call label="Проверка женщины" name="Test Female"/>
<menu_item_check label="Разрешить выбор аватара" name="Allow Select Avatar"/>
</menu>
- <menu label="Скорость анимации" name="Animation Speed">
- <menu_item_call label="Ускорить все анимации на 10%" name="All Animations 10 Faster"/>
- <menu_item_call label="Замедлить все анимации на 10%" name="All Animations 10 Slower"/>
- <menu_item_call label="Восстановить скорость анимаций" name="Reset All Animation Speed"/>
- <menu_item_check label="Анимация медленных движений" name="Slow Motion Animations"/>
- </menu>
<menu_item_call label="Скинуть параметры" name="Force Params to Default"/>
<menu_item_check label="Данные об анимации" name="Animation Info"/>
+ <menu_item_check label="Анимация медленных движений" name="Slow Motion Animations"/>
<menu_item_check label="Показать взгляд" name="Show Look At"/>
<menu_item_check label="Показать указание" name="Show Point At"/>
<menu_item_check label="Отладка обновленных движений суставов" name="Debug Joint Updates"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml
index c465966fc7..35485bb292 100755
--- a/indra/newview/skins/default/xui/tr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml
@@ -313,7 +313,7 @@
<menu_item_call label="Seçilen Doku Bilgi Temeli" name="Selected Texture Info Basis"/>
<menu_item_check label="Telkafes" name="Wireframe"/>
<menu_item_check label="Görünen Nesneler İçin Gölgeleme" name="Object-Object Occlusion"/>
- <menu_item_check label="Işıklandırma ve Gölgeler" name="Lighting and Shadows"/>
+ <menu_item_check label="Işıklandırma ve Gölgeler" name="Advanced Lighting Model"/>
<menu_item_check label="Güneş/Ay/Projektörlerden Gelen Gölgeler" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO ve Gölge Yumuşatma" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="GL Hata Ayıklama" name="Debug GL"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml
index 09bdc57819..d4844b191b 100755
--- a/indra/newview/skins/default/xui/zh/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml
@@ -313,7 +313,7 @@
<menu_item_call label="已選取材質資訊基礎" name="Selected Texture Info Basis"/>
<menu_item_check label="線框" name="Wireframe"/>
<menu_item_check label="物件導向的遮蔽" name="Object-Object Occlusion"/>
- <menu_item_check label="光線和陰影" name="Lighting and Shadows"/>
+ <menu_item_check label="光線和陰影" name="Advanced Lighting Model"/>
<menu_item_check label="來自日/月/投影物的陰影" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="屏幕空間環境光遮蔽和陰影平滑技術" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="GL 除錯" name="Debug GL"/>
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 01195d1269..6f57daf151 100755
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -39,6 +39,7 @@
#include "../llvovolume.h"
#include "../../llprimitive/llmediaentry.cpp"
+#include "../../llprimitive/llmaterialid.cpp"
#include "../../llprimitive/lltextureentry.cpp"
#include "../../llmessage/tests/llcurl_stub.cpp"
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 2578c81224..5e08e54b7c 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -172,7 +172,7 @@ class ViewerManifest(LLManifest):
def app_name(self):
app_suffix='Test'
channel_type=self.channel_lowerword()
- if channel_type == 'release' :
+ if channel_type.startswith('release') :
app_suffix='Viewer'
elif re.match('^(beta|project).*',channel_type) :
app_suffix=self.channel_unique()
@@ -182,8 +182,8 @@ class ViewerManifest(LLManifest):
icon_path="icons/"
channel_type=self.channel_lowerword()
print "Icon channel type '%s'" % channel_type
- if channel_type == 'release' :
- icon_path += channel_type
+ if channel_type.startswith('release') :
+ icon_path += 'release'
elif re.match('^beta.*',channel_type) :
icon_path += 'beta'
elif re.match('^project.*',channel_type) :
@@ -242,7 +242,7 @@ class WindowsManifest(ViewerManifest):
def final_exe(self):
app_suffix="Test"
channel_type=self.channel_lowerword()
- if channel_type == 'release' :
+ if channel_type.startswith('release') :
app_suffix=''
elif re.match('^(beta|project).*',channel_type) :
app_suffix=''.join(self.channel_unique().split())
@@ -366,6 +366,7 @@ class WindowsManifest(ViewerManifest):
self.path("zlib1.dll")
self.path("vivoxplatform.dll")
self.path("vivoxoal.dll")
+ self.path("ca-bundle.crt")
# Security
self.path("ssleay32.dll")
@@ -726,10 +727,11 @@ class DarwinManifest(ViewerManifest):
'libvivoxoal.dylib',
'libvivoxsdk.dylib',
'libvivoxplatform.dylib',
+ 'ca-bundle.crt',
'SLVoice',
):
self.path2basename(libdir, libfile)
-
+
# our apps
for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
# plugin launcher
@@ -1038,9 +1040,6 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libboost_signals-mt.so.*")
self.path("libboost_system-mt.so.*")
self.path("libboost_thread-mt.so.*")
- self.path("libbreakpad_client.so.0.0.0")
- self.path("libbreakpad_client.so.0")
- self.path("libbreakpad_client.so")
self.path("libcollada14dom.so")
self.path("libdb*.so")
self.path("libcrypto.so.*")
diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp
index 2689eaa15e..2488af1d7f 100755
--- a/indra/test/llsaleinfo_tut.cpp
+++ b/indra/test/llsaleinfo_tut.cpp
@@ -156,7 +156,7 @@ namespace tut
ensure("importStream() fn failed ",
llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
- llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());
+ llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());
}
template<> template<>
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index 3357ad812d..8f33b2ad58 100755
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -137,7 +137,7 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
//{
// printable_params["params"]["passwd"] = "*******";
//}
- LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self)
+ LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self)
<< " with uri '" << uri << "', parameters " << printable_params << LL_ENDL;
// Arriving in SRVRequest state
@@ -146,23 +146,23 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
LLSD rewrittenURIs;
{
- LLEventTimeout filter(replyPump);
- sendProgressEvent("offline", "srvrequest");
+ LLEventTimeout filter(replyPump);
+ sendProgressEvent("offline", "srvrequest");
- // Request SRV record.
- LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;
+ // Request SRV record.
+ LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;
- // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
+ // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
F32 seconds_to_timeout = 5.0f;
if(login_params.has("cfg_srv_timeout"))
{
seconds_to_timeout = login_params["cfg_srv_timeout"].asReal();
}
- // If the SRV request times out (e.g. EXT-3934), simulate response: an
- // array containing our original URI.
- LLSD fakeResponse(LLSD::emptyArray());
- fakeResponse.append(uri);
+ // If the SRV request times out (e.g. EXT-3934), simulate response: an
+ // array containing our original URI.
+ LLSD fakeResponse(LLSD::emptyArray());
+ fakeResponse.append(uri);
filter.eventAfter(seconds_to_timeout, fakeResponse);
std::string srv_pump_name = "LLAres";
@@ -172,13 +172,13 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
}
// Make request
- LLSD request;
- request["op"] = "rewriteURI";
- request["uri"] = uri;
- request["reply"] = replyPump.getName();
- rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
- // EXP-772: If rewrittenURIs fail, try original URI as a fallback.
- rewrittenURIs.append(uri);
+ LLSD request;
+ request["op"] = "rewriteURI";
+ request["uri"] = uri;
+ request["reply"] = replyPump.getName();
+ rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
+ // EXP-772: If rewrittenURIs fail, try original URI as a fallback.
+ rewrittenURIs.append(uri);
} // we no longer need the filter
LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction"));
@@ -230,7 +230,7 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
// Still Downloading -- send progress update.
sendProgressEvent("offline", "downloading");
}
-
+
LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL;
status = mAuthResponse["status"].asString();